Creating cameras that follows coordinates and angles in lua

I need help to (find a function to) create cameras (render points i think their called) controlled by coordinates and angels in lua

-bump-

Why can’t you just constrain it or parent it?

No, im trying to make it follow a 3d track

[editline]10:22PM[/editline]

Okey, i found this: http://wiki.garrysmod.com/?title=Cam
Someone give me some help about that lib??

-buuuump!!!-

Yeh cam is what I use to draw 2d elements in the 3D world. I think you must. Always make a sent for it. Have a look at cam.3D2D and there is an example on there and read the notes at the bottom. The topic about drawing text near this topic has an example scoreboard in 3D so have a look at that and see if you can edit to you liking =D

Isnt the cam lib for making virtual cameras?

No it’s for projecting

Damn
Then, back to start

What functions is used in etc. the rt camera?

Do you want something like Catmull-Rom spline cameras?

What do that do?

Edit:

The only thing i want is a rt camera controlled by coordinates instead of physics

Go look at renderpoint like i told you too :smiley:

Sorry for beeng an idiot, but link to renderpoint? :smiley:

Okay, here is the rt camera code:

[lua]
TOOL.Category = “Render”
TOOL.Name = “#RT Camera”
TOOL.Command = nil
TOOL.ConfigName = nil

TOOL.ClientConVar[ “locked” ] = “0”
TOOL.ClientConVar[ “key” ] = “0”

cleanup.Register( “cameras” )

GAMEMODE.RTCameraList = GAMEMODE.RTCameraList or {}

TOOL.LeftClickAutomatic = true
TOOL.RightClickAutomatic = false
TOOL.RequiresTraceHit = false

// Global to hold the render target camera entity
RenderTargetCamera = nil
RenderTargetCameraProp = nil

function TOOL:LeftClick( trace )

if (CLIENT) then return end

local key		= self:GetClientNumber( "key" )
if (key == -1) then return false end

local ply 		= self:GetOwner()
local locked	= self:GetClientNumber( "locked" )
local pid 		= ply:UniqueID()

GAMEMODE.RTCameraList[ pid ] 	= GAMEMODE.RTCameraList[ pid ] or {}
local CameraList = GAMEMODE.RTCameraList[ pid ]

local Pos = trace.StartPos// + trace.Normal * 16

// If the camera already exists then just move it into position
if (CameraList[ key ] && CameraList[ key ] != NULL ) then

	local ent = CameraList[ key ]
	
	// Remove all constraints
	constraint.RemoveAll( ent )

	ent:SetPos( Pos )
	ent:SetAngles( ply:EyeAngles() )
	
	local phys = ent:GetPhysicsObject()
	if (phys:IsValid()) then phys:Sleep() end
	
	ent:SetLocked( locked )
	ent:SetTracking( NULL,Vector(0))

	if !RenderTargetCamera then UpdateRenderTarget( camera ) end

	return false, ent
	
end

local camera = ents.Create( "gmod_rtcameraprop" )
if (!camera:IsValid()) then return false end
	
	camera:SetAngles( ply:EyeAngles() )
	camera:SetPos( Pos )
	camera:Spawn()
	
	camera:SetKey( key )
	camera:SetPlayer( ply )
	camera:SetLocked( locked )

	numpad.OnDown(	ply,		key, 	"RTCamera_Use", 	camera )
	
	camera:SetTracking( NULL, Vector(0) )

undo.Create("RT Camera")
	undo.AddEntity( camera )
	undo.SetPlayer( ply )
undo.Finish()

ply:AddCleanup( "cameras", camera )


CameraList[ key ] = camera

if !RenderTargetCamera || #ents.FindByClass( "gmod_rtcameraprop" ) == 1 then UpdateRenderTarget( camera ) end

return false, camera

end

// Global Function to update the render target
function UpdateRenderTarget( Ent )

if ( !Ent || !Ent:IsValid() ) then return end

if ( !RenderTargetCamera || !RenderTargetCamera:IsValid() ) then

	RenderTargetCamera = ents.Create( "point_camera" )
	RenderTargetCamera:SetKeyValue( "GlobalOverride", 1 )
	RenderTargetCamera:Spawn()
	RenderTargetCamera:Activate()
	RenderTargetCamera:Fire( "SetOn", "", 0.0 )

end
Pos = Ent:LocalToWorld( Vector( 12,0,0) )
RenderTargetCamera:SetPos(Pos)
RenderTargetCamera:SetAngles(Ent:GetAngles())
RenderTargetCamera:SetParent(Ent)

RenderTargetCameraProp = Ent

end

function TOOL:RightClick( trace )

_, camera = self:LeftClick( trace )

if (CLIENT) then return false end

if ( !camera || !camera:IsValid() ) then return end

if ( trace.Entity:IsWorld() ) then

	trace.Entity = self:GetOwner()
	trace.HitPos = self:GetOwner():GetPos()

end

camera:SetTracking( trace.Entity, trace.Entity:WorldToLocal( trace.HitPos ))

return false

end

if (CLIENT) then

local rtcamera_draw = CreateClientConVar( “rtcamera_draw”, “0”, false, false )

local RTWindow = nil

local function OpenRTWindow( player, command, arguments )

LocalPlayer():ConCommand( "rtcamera_draw 1" )

if (RTWindow) then
	RTWindow:SetVisible( true )
return end

// Close the window when it's clicked on
local function RTAction( panel, message, param1, param2 )
	if (message == "MouseReleased") then
		RTWindow:SetVisible( false )
	end
end

// We override the paint function just so it doesn't draw anything
local function RTPaint( panel )
	return true
end

RTWindow = vgui.Create( "Frame" )
RTWindow:SetName( "Render Target" )
RTWindow:SetPos( 25, 25 )
RTWindow:SetSize( ScrW() * 0.25, ScrH() * 0.25 )
RTWindow:SetMouseInputEnabled( true )
RTWindow:SetKeyBoardInputEnabled( false )
RTWindow:SetVisible( true )
RTWindow:SetActionFunction( RTAction )
RTWindow:SetPaintFunction( RTPaint )

end

concommand.Add( “rtcamera_window”, OpenRTWindow )

local rtTexture = surface.GetTextureID( “pp/rt” )
local rtSize = {}

local function DrawRTTexture()

if ( !rtcamera_draw:GetBool() ) then

	if (RTWindow && RTWindow:IsVisible()) then
		RTWindow:SetVisible( false )
	end

return end

if (RTWindow) then 

	rtSize.set = true
	rtSize.x, rtSize.y = RTWindow:GetPos()
	rtSize.w, rtSize.h = RTWindow:GetSize()

end

if (!rtSize.set) then return end

if (RTWindow && RTWindow:IsVisible()) then 

	surface.SetDrawColor( 0, 0, 0, 150 )
	surface.DrawRect( 0, 0, ScrW(), ScrH() )

end

rtTexture = surface.GetTextureID( "pp/rt" )
surface.SetTexture( rtTexture )
surface.SetDrawColor( 255, 255, 255, 255 )
surface.DrawTexturedRect( rtSize.x , rtSize.y, rtSize.w, rtSize.h ) 


if (RTWindow && RTWindow:IsVisible()) then 
	
	surface.SetDrawColor( 255, 255, 255, 255 )
	
	surface.DrawOutlinedRect( rtSize.x , rtSize.y, rtSize.w, rtSize.h )
	surface.DrawOutlinedRect( rtSize.x , rtSize.y, rtSize.w, 28 )
	
	surface.SetDrawColor( 255, 255, 255, 50 )
	surface.DrawRect( rtSize.x , rtSize.y, rtSize.w, 28 )
	
end

surface.SetDrawColor( 0, 0, 0, 220 )
surface.DrawOutlinedRect( rtSize.x-1 , rtSize.y-1, rtSize.w+2, rtSize.h+2 )

end

hook.Add( “HUDPaint”, “DrawRTTexture”, DrawRTTexture )

function TOOL:DrawToolScreen( w, h )

rtTexture = surface.GetTextureID( "pp/rt" )
surface.SetTexture( rtTexture )
surface.SetDrawColor( 255, 255, 255, 255 )
surface.DrawTexturedRect( 0, 26, w, h - 48 ) 

end

end
[/lua]

Edit:

Whats the code tag?

[noparse][lua]lua code here[/lua][/noparse]

You could use the CalcView hook to control the player’s view, or render.RenderView if you want to draw multiple views on the screen.

You can’t copy the RT camera’s code and expect to be able to change a few lines and achieve what you
want.

Here is something similar to what you want using Catmull-Rom splines:

[lua]local Track = {
Vector(-100, -100, -100),
Vector(-50, -50, -50),
Vector(0, 0, 0),
Vector(100, 32, 300),
Vector(200, 320, 400),
Vector(300, 520, 600),
Vector(300, 1430, 1200),
Vector(200, 2000, 100),
Vector(200, 5000, 0)
– Points on the ‘3D Track’
}

local SplineWeight = 0;
local CurrentTrackPoint = 2;

local speed = 3; – How many seconds it takes to move between two points.
hook.Add(“CalcView”, “FollowTrack”, function(ply, orig, ang, fov)
local c = CurrentTrackPoint; – Name was too long
local t = SplineWeight;
print(Track[c]);
if Track[c-1] and Track[c] and Track[c+1] and Track[c+2] then
ply.CRSpline = math.CatmullRom3D(Track[c-1], Track[c], Track[c+1], Track[c+2]);
ply.CRSplineD = math.CatmullRomDerivative3D(Track[c-1], Track[c], Track[c+1], Track[c+2]);
local view = {};
view.origin = ply.CRSpline(t);
view.angles = ply.CRSplineD(t):Angle();
view.fov = fov;
SplineWeight = t + FrameTime()/speed;
if SplineWeight > 1 then
SplineWeight = 0;
CurrentTrackPoint = c + 1;
if CurrentTrackPoint > #Track-2 then
CurrentTrackPoint = 2;
end
end
return view;
end
end);[/lua]

You need to have these functions somewhere in autorun or includes/extensions for this to work:

[lua]function math.CatmullRom(p1, p2, p3, p4)
return function(t)
t = math.Clamp(t, 0, 1);
return 0.5 * ((-p1 + 3p2 -3p3 + p4)ttt
+ (2
p1 -5p2 + 4p3 - p4)tt
+ (-p1+p3)t
+ 2
p2);
end
end

function math.CatmullRom3D(p1, p2, p3, p4)
local x = math.CatmullRom(p1.x, p2.x, p3.x, p4.x);
local y = math.CatmullRom(p1.y, p2.y, p3.y, p4.y);
local z = math.CatmullRom(p1.z, p2.z, p3.z, p4.z);
return function(t)
return Vector(x(t), y(t), z(t));
end
end

function math.CatmullRomDerivative(p1, p2, p3, p4)
return function(t)
t = math.Clamp(t, 0, 1);
return 0.5 * ((-3p1 + 9p2 -9p3 + 3p4)tt
+ (4p1 -10p2 + 8p3 -2p4)*t
+ (-p1+p3));
end
end

function math.CatmullRomDerivative3D(p1, p2, p3, p4)
local x = math.CatmullRomDerivative(p1.x, p2.x, p3.x, p4.x);
local y = math.CatmullRomDerivative(p1.y, p2.y, p3.y, p4.y);
local z = math.CatmullRomDerivative(p1.z, p2.z, p3.z, p4.z);
return function(t)
return Vector(x(t), y(t), z(t));
end
end[/lua]

[editline]08:17PM[/editline]

The first vector in the Track table, and the last two are never reached, they are there because because catmull-rom splines need 4 nodes to calculate a curve between two of them.

[editline]08:18PM[/editline]

Also, it probably isn’t necessary to calculate the spline every frame, but I can’t be bothered to fix it.

Why do people “help” people like this OP.

All he’s doing is asking you guys to code him cameras, he hasnt shown any work of his own or any actual initiative.

Because we are good people.