Author Topic: 3D Camera Lib  (Read 3815 times)

Offline bigsofty

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 2510
    • View Profile
3D Camera Lib
« on: 2009-Oct-02 »
EDIT: Use the Quaternion based camera lib (posted here as a sticky), use this only for ground objects and only then if you want to save a little speed.

A little camera lib, it runs off vectors, so you need the vector lib too, included.

You can use functions like, CameraViewVec to fire projectiles from the camera along the current camera view.

I will write a decent doc/example as soon as I get back to my main GLB computer, I'm away from home just now.

Cheers,


Ian


Camera Lib...

Code: GLBasic [Select]
TYPE Tcamera
        cameraPosition AS Tvector
        cameraTarget AS Tvector
        cameraUpVector AS Tvector
        radius = 1
        moveDist = 1
        hRadians
        vRadians
ENDTYPE


FUNCTION SetCameraPosition: camera AS Tcamera, cPosition AS Tvector, h ,v
    GLOBAL cPI = 3.1415926535
    camera.cameraPosition = cPosition
    camera.cameraTarget = vector_zero()
    camera.cameraUpVector = vector_zero()
    camera.cameraUpVector.y = -1
    camera.hRadians = h
    camera.vRadians = v
    RotateCamera(camera,0,0)
ENDFUNCTION


FUNCTION RotateCamera: camera AS Tcamera, h,v
    camera.hRadians = camera.hRadians + h
    camera.vRadians = camera.vRadians + v
    camera.cameraTarget.y = camera.cameraPosition.y + (camera.radius*SIN(camera.vRadians))
    camera.cameraTarget.x = camera.cameraPosition.x + (camera.radius*COS(camera.vRadians)*COS(camera.hRadians))
    camera.cameraTarget.z = camera.cameraPosition.z + (camera.radius*COS(camera.vRadians)*SIN(camera.hRadians))
    camera.cameraUpVector.x = camera.cameraPosition.x-camera.cameraTarget.x
    camera.cameraUpVector.y = ABS(camera.cameraPosition.y+(camera.radius*SIN(camera.vRadians+cPI/2)))
    camera.cameraUpVector.z = camera.cameraPosition.z-camera.cameraTarget.z
ENDFUNCTION


FUNCTION SlideCamera: camera AS Tcamera, h, v
    camera.cameraPosition.y = camera.cameraPosition.y + (v*camera.moveDist)
    camera.cameraPosition.x = camera.cameraPosition.x + (h*camera.moveDist*COS(camera.hRadians+cPI/2))
    camera.cameraPosition.z = camera.cameraPosition.z + (h*camera.moveDist*SIN(camera.hRadians+cPI/2))
    RotateCamera(camera,0,0)
ENDFUNCTION


FUNCTION MoveCamera: camera AS Tcamera, d
    camera.cameraPosition.y = camera.cameraPosition.y + (d*camera.moveDist*(SIN(camera.vRadians)))
    camera.cameraPosition.x = camera.cameraPosition.x + (d*camera.moveDist*(COS(camera.vRadians)*COS(camera.hRadians)))
    camera.cameraPosition.z = camera.cameraPosition.z + (d*camera.moveDist*(COS(camera.vRadians)*SIN(camera.hRadians)))
    RotateCamera(camera,0,0)
ENDFUNCTION


FUNCTION CameraViewVec AS Tvector: camera AS Tcamera
    LOCAL result AS Tvector
    result.y = (SIN(camera.vRadians))
    result.x = (COS(camera.vRadians)*COS(camera.hRadians))
    result.z = (COS(camera.vRadians)*SIN(camera.hRadians))
    RETURN result
ENDFUNCTION


Vector Lib...

Code: GLBasic [Select]
// --------------------------------- //

TYPE Tvector
        x
        y
        z
        magnitude
ENDTYPE

FUNCTION setup_veclib:
//used TO normalize vector
GLOBAL vector_tol = 0.0001
ENDFUNCTION

FUNCTION vector_calcMagnitude: vec AS Tvector
        //calc the magnitude of a vector AND stor in vector
        vec.magnitude=SQR(vec.x*vec.x + vec.y*vec.y + vec.z*vec.z)
ENDFUNCTION

FUNCTION vector_normalise: vec AS Tvector
    LOCAL m
        //normalize a vector so it's length = 1 AND apply tolerance based on our constant tolerance value
        m=SQR(SQR(vec.x*vec.x + vec.y*vec.y + vec.z*vec.z) )
        IF m<= vector_tol THEN m=1
        vec.x=vec.x/m
        vec.y=vec.y/m
        vec.z=vec.z/m
        IF ABS(vec.x)<vector_tol THEN vec.x=0
        IF ABS(vec.y)<vector_tol THEN vec.y=0
        IF ABS(vec.z)<vector_tol THEN vec.z=0
ENDFUNCTION

FUNCTION vector_new AS Tvector: x,y,z,m
        LOCAL result AS Tvector
        result.x=x
        result.y=y
        result.z=z
        result.magnitude=m
        RETURN result
ENDFUNCTION

FUNCTION vector_reverse: vec AS Tvector
        //reverse a vector
        vec.x=-vec.x
        vec.y=-vec.y
        vec.z=-vec.z
ENDFUNCTION

FUNCTION vector_add AS Tvector: vec1 AS Tvector, vec2 AS Tvector
        //add two vectors together AND RETURN the resulting vector
        LOCAL result AS Tvector
        result.x=vec1.x+vec2.x
        result.y=vec1.y+vec2.y
        result.z=vec1.z+vec2.z
        RETURN result
ENDFUNCTION

FUNCTION vector_subtract AS Tvector: vec1 AS Tvector, vec2 AS Tvector
        //subtract vec1 from vec2 AND RETURN the resulting vector
        LOCAL result AS Tvector
        result.x=vec1.x-vec2.x
        result.y=vec1.y-vec2.y
        result.z=vec1.z-vec2.z
        RETURN result
ENDFUNCTION

FUNCTION vector_scalarMultiply AS Tvector: vec1 AS Tvector, scale
        //scalar multiplication of a vector with result returned AS new vector
        //used TO scale a vector by &#39;scale&#39;
        LOCAL result AS Tvector
        result.x=vec1.x*scale
        result.y=vec1.y*scale
        result.z=vec1.z*scale
        RETURN result
ENDFUNCTION

FUNCTION vector_scalarDivision AS Tvector: vec1 AS Tvector, scale
        //scalar division of a vector with result returned AS new vector
        //used TO scale a vector
        LOCAL result AS Tvector
        result.x=vec1.x/scale
        result.y=vec1.y/scale
        result.z=vec1.z/scale
        RETURN result
ENDFUNCTION

FUNCTION vector_conjugate AS Tvector: vec1 AS Tvector
        //conjugate operator takes the negative of each vector component
        //can be used when subtracting one vector from another OR FOR
        //reversing the direction of a vector.
        //applying conjugate is the same AS reversing a vector
        //returns a new vector
        LOCAL result AS Tvector
        result.x=-vec1.x
        result.y=-vec1.y
        result.z=-vec1.z
        RETURN result
ENDFUNCTION

FUNCTION vector_crossProduct AS Tvector: vec1 AS Tvector, vec2 AS Tvector
        //takes vec1 AND vec2 AND returns the cross product vec1 X vec2
        //the cross product is a vector perpendicular TO both vec1 AND vec2
        //this is the normal of 2 vectors
        LOCAL result AS Tvector
        result.x=(vec1.y*vec2.z) - (vec1.z*vec2.y)
        result.y=(vec1.z*vec2.x) - (vec1.x*vec2.z)
        result.z=(vec1.x*vec2.y) - (vec1.y*vec2.x)
        RETURN result
ENDFUNCTION

FUNCTION vector_dotProduct: vec1 AS Tvector, vec2 AS Tvector
        //calculate AND RETURN the dot product of 2 vectors (distance)
        LOCAL result
        result=(vec1.x*vec2.x)+(vec1.y*vec2.y)+(vec1.z*vec2.z)
        RETURN result
ENDFUNCTION

FUNCTION vector_tripleScalarProduct: vec1 AS Tvector, vec2 AS Tvector, vec3 AS Tvector
        //calculate the triple scalar FUNCTION AND RETURN it
        LOCAL result
        result=           vec1.x * ( (vec2.y*vec3.z ) - (vec2.z * vec3.y) )
        result=result + ( vec1.y * ( (-vec2.x*vec3.z) + (vec2.z * vec3.x) ) )
        result=result + ( vec1.z * ( ( vec2.x*vec3.y) + (vec2.y * vec3.x) ) )
        RETURN result
ENDFUNCTION

FUNCTION vector_zero AS Tvector:
        //calculate the triple scalar FUNCTION AND RETURN it
        LOCAL result AS Tvector
        result.x = 0
        result.y = 0
        result.z = 0
        result.magnitude = 0
        RETURN result
ENDFUNCTION

FUNCTION Vector_RotateAroundX AS Tvector: vec1 AS Tvector, angle
        LOCAL result AS Tvector
        result.x = vec1.x
        result.y = COS(angle) * vec1.y - SIN(angle) * vec1.z
        result.z = SIN(angle) * vec1.y + COS(angle) * vec1.z
        RETURN result
ENDFUNCTION

FUNCTION Vector_RotateAroundY AS Tvector: vec1 AS Tvector, angle
        LOCAL result AS Tvector
        result.x  = COS(angle) * vec1.x + SIN(angle) * vec1.z
        result.y = vec1.y
        result.z = -SIN(angle) * vec1.x + COS(angle) * vec1.z
        RETURN result
ENDFUNCTION

FUNCTION Vector_RotateAroundZ AS Tvector: vec1 AS Tvector, angle
        LOCAL result AS Tvector
        result.x = COS(angle) * vec1.x - SIN(angle) * vec1.y
        result.y = SIN(angle) * vec1.x + COS(angle) * vec1.y
        result.z = vec1.z
        RETURN result
ENDFUNCTION

FUNCTION Vector_RotateAroundVec AS Tvector: vec1 AS Tvector, vec2 AS Tvector, angle
        LOCAL result AS Tvector, cosa, sina, ecosa
        cosa = COS(angle)
        sina = SIN(angle)
        ecosa = 1.0 - cosa
        result.x = vec1.x * (cosa + vec2.x * vec2.x * ecosa) + vec1.y * (vec2.x * vec2.y * ecosa - vec2.z * sina) + vec1.z * (vec2.x * vec2.z * ecosa + vec2.y * sina)
        result.y = vec1.x * (vec2.y * vec2.x * ecosa + vec2.z * sina) + vec1.y * (cosa + vec2.y * vec2.y * ecosa) + vec1.z * (vec2.y * vec2.z * ecosa - vec2.x * sina)
        result.z = vec1.x * (vec2.z * vec2.x * ecosa - vec2.y * sina) + vec1.y * (vec2.z * vec2.y * ecosa + vec2.x * sina) + vec1.z * (cosa + vec2.z * vec2.z * ecosa)
        RETURN result
ENDFUNCTION
 
« Last Edit: 2009-Nov-26 by bigsofty »
Cheers,

Ian.

“It is practically impossible to teach good programming style to students that have had prior exposure to BASIC.  As potential programmers, they are mentally mutilated beyond hope of regeneration.”
(E. W. Dijkstra)

Offline Hemlos

  • To boldy go where no pixel has gone before!
  • Global Moderator
  • Prof. Inline
  • *******
  • Posts: 1578
  • Particle Hawk
    • View Profile
Re: 3D Camera Lib
« Reply #1 on: 2009-Oct-02 »
Thanks bigsofty, this is handy.
Im looking forward to your example camera.
Curious, is this 3 or 6 degrees of freedom?
Volume_of_Earth(km^3) = 4/3*3.14*POW(6371.392896,3)

Offline bigsofty

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 2510
    • View Profile
Re: 3D Camera Lib
« Reply #2 on: 2009-Oct-02 »
Your very welcome bud.

6 DOF, its quite simple to use if you have used vectors before.
Cheers,

Ian.

“It is practically impossible to teach good programming style to students that have had prior exposure to BASIC.  As potential programmers, they are mentally mutilated beyond hope of regeneration.”
(E. W. Dijkstra)

Offline Hemlos

  • To boldy go where no pixel has gone before!
  • Global Moderator
  • Prof. Inline
  • *******
  • Posts: 1578
  • Particle Hawk
    • View Profile
Re: 3D Camera Lib
« Reply #3 on: 2009-Oct-22 »
I was looking at this library,
i noticed the rotation is horizontal and vertical.

It doesnt seem to "roll" around the camera z axis.

Care to describe just a little how to do 6dof?
Please?
Volume_of_Earth(km^3) = 4/3*3.14*POW(6371.392896,3)

Offline bigsofty

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 2510
    • View Profile
Re: 3D Camera Lib
« Reply #4 on: 2009-Oct-23 »
Well, your right, I can't remember how I changed it to add Roll... this code is very old code.

I believe I used the vector lib to manipulate the up vector of the GLB camera...

So...

GLOBAL cam AS Tcamera
GLOBAL camroll_vec AS Tvector;
camroll_vec = Vector_RotateAroundX(cam.cameraUpVector, angle) // For the X axis
X_CAMERAUP camroll_vec.x, camroll_vec.y, camroll_vec.z
X_CAMERA cam.cameraPosition.x, cam.cameraPosition.y, cam.cameraPosition.z, cam.cameraTarget.x, cam.cameraTarget.y, cam.cameraTarget.z
cam.cameraUpVector = camroll_vec

...

I'm not in front of my GLB PC right now, so this is untested.

After another quick look, I am unsure if I would advise using this for a full 6Dof, as I don't see anything for Gimbal lock avoidance either... so unless you need a simple camera, I would avoid this one for now. To avoid the whole Gimbal trap, I would advise quaternions, in any case. If I find a more up to date one when I get home, I'll post it.
Cheers,

Ian.

“It is practically impossible to teach good programming style to students that have had prior exposure to BASIC.  As potential programmers, they are mentally mutilated beyond hope of regeneration.”
(E. W. Dijkstra)

Offline djtoon

  • Dr. Type
  • ****
  • Posts: 290
    • View Profile
Re: 3D Camera Lib
« Reply #5 on: 2011-Feb-15 »
well !!!! this lib shakes as well :(

whats the problem

Offline Hemlos

  • To boldy go where no pixel has gone before!
  • Global Moderator
  • Prof. Inline
  • *******
  • Posts: 1578
  • Particle Hawk
    • View Profile
Re: 3D Camera Lib
« Reply #6 on: 2012-Jun-14 »
Yes, this lib works, perfectly for cameras...if anyone was wondering.
Gimbal lock is only present in objects being viewed by a camera.
Theres no solution to object Gimbal Lock other than 2d overlays..

To avoid object gimbal lock, whether you use quaternion or simple opengl rotations:
1. Do this with another viewport
2 . use a quaternion camera and rotate and move it around the object in the second view port(not visible to player)
3. Take and a screenshot and overlay it in the 3d world...dont forget to apply lighting before the screenshot of the object.
You might need to do multiple screenshots, in order to overlap 2d on 3d and more 3d between cam and obj.
Its tricky, but itll work, im sure of it....its alot of work, thats why flight simulators are some of the most expensive peices of software on the market!

I have been tinkering with a few 3d projects relating to flight sims, and this is the ultimate way to rotate your cam.
I felt the urge to reitterate on this thread and library because, well, quaternions are mind boggling EVEN when you figgure them out.


@djtoon and everyone playing with this lib:
Important to know....keep the camera around the center of the 3d world. IE somewhere near world position 0,0,0
Make the rest of the world move thier XYZ when you move...and the camera only to rotate and wobble etc.
If you do it like this, then you can make your world as big as you want without getting the "shakes".
And after ALOT of testing, i found that the camera can be roated in all 6 degrees of freedom!
-Thanks Bigsofty!
« Last Edit: 2012-Jun-14 by Hemlos »
Volume_of_Earth(km^3) = 4/3*3.14*POW(6371.392896,3)