BlitzMax 3D Camera Troubles

Sage
Posts: 1,066
Joined: 2004.07
Post: #1
I'm trying to write up a small 3D engine in BlitzMax. I'm trying to get my camera to work (well I'm just trying to get mouse input done, the rest is easy) but the camera doesn't look up or down. I also can't get it to put the mouse back in the center of the screen or hide the mouse. Any suggestions/links/advice/help? Thanks a ton. Here's the code. I did just right this up in the last few hours (it's 3:34am here in good ole Michigan) so I may have made some of those sleepy-coder mistakes. I apologize if this post is poorly proofread as that's also a result of sleep deprivation.

Code:
(settings.bmx)
Const width = 800
Const height = 600
Const ratio = width / height
Const middleX = 400
Const middleY = 300

Code:
(CRYVector.bmx)
Type CRYVector
    Field x#,y#,z#
    Field magnitude#
    
    Method New()
        x = 0
        y = 0
        z = 0
        magnitude = 0
    EndMethod
    
    Method FindMagnitude()
        magnitude = Sqr((x * x) + (y * y) + (z * z))
    EndMethod
    
    Method Normalize()
        FindMagnitude()
        x = x / magnitude
        y = y / magnitude
        z = z / magnitude
        magnitude = 1
    EndMethod
    
EndType

Function DotProduct(a:CRYVector Var, b:CRYVector Var)
    Return ((a.x * b.x) + (a.y * b.y) + (a.z * b.z))
EndFunction

Function CrossProduct:CRYVector(a:CRYVector Var, b:CRYVector Var)
    Local temp:CRYVector = New CRYVector
    temp.x=((a.y * b.z) - (a.z * b.y))
    temp.y=((a.z * b.x) - (a.x * b.z))
    temp.z=((a.x * b.y) - (a.y * b.x))
    Return temp
EndFunction

Function Distance(a:CRYVector Var, b:CRYVector Var)
    Return Sqr(((b.x - a.x) * (b.x - a.x)) + ((b.y - a.y) * (b.y - a.y)) + ((b.z - a.z) * (b.z - a.z)))
EndFunction

Code:
(CRYCamera.bmx)
Import "settings.bmx"
Import "CRYVector.bmx"

Type CRYCamera
    Field position:CRYVector
    Field target:CRYVector
    Field direction:CRYVector
    Field strafe:CRYVector
    Field up:CRYVector
    Field perspective
    Field currentRotation#
    
    Method New()
        position = New CRYVector
        target = New CRYVector
        direction = New CRYVector
        strafe = New CRYVector
        up = New CRYVector
        
        position.x = 0
        position.y = 6
        position.z = 0
        
        target.x = 0
        target.y = 6
        target.z = 10
        
        up.x = 0
        up.y = 1
        up.z = 0
    EndMethod
    
    Method FindDirection()
        direction.x = target.x - position.x
        direction.y = target.y - position.y
        direction.z = target.z - position.z
        direction.Normalize()
    EndMethod
    
    Method FindStrafe()
        FindDirection()
        strafe = CrossProduct(direction,up)
        strafe.Normalize()
    EndMethod
    
    Method RotateAtPosition(angle# Var, vector:CRYVector Var)
        Local tempV:CRYVector = New CRYVector
        Local tempD:CRYVector = New CRYVector
        
        tempD.x = target.x - position.x
        tempD.y = target.y - position.y
        tempD.z = target.z - position.z
        
        Local cosTheta# = Cos(angle)
        Local sinTheta# = Sin(angle)
        
        Local x# = vector.x
        Local y# = vector.y
        Local z# = vector.z
        
        tempV.x = ((cosTheta + (1 - cosTheta) * x * x) * tempD.x)
        tempV.x:+ (((1 - cosTheta) * x * y - z * sinTheta) * tempD.y)
        tempV.x:+ (((1 - cosTheta) * x * z + y * sinTheta) * tempD.z)
        
        tempV.y = (((1 - cosTheta) * x * y + z * sinTheta) * tempD.x)
        tempV.y:+ ((cosTheta + (1 - cosTheta) * y * y) * tempD.y)
        tempV.y:+ (((1 - cosTheta) * y * z - x * sinTheta) * tempD.z)
        
        tempV.z = (((1 - cosTheta) * x * z - y * sinTheta) * tempD.x)
        tempV.z:+ (((1 - cosTheta) * y * z + x * sinTheta) * tempD.y)
        tempV.z:+ ((cosTheta + (1 - cosTheta) * z * z) * tempD.z)
        
        target.x = position.x + tempV.x
        target.y = position.y + tempV.y
        target.z = position.z + tempV.z
        
    EndMethod
    
    Method MouseInput()
        If (( MouseX() = middleX ) And (MouseY() = middleY))
            Return
        Else
            Local angleY# = middleX - MouseX()
            Local angleZ# = middleY - MouseY()
            
            angleY = angleY / 1000.0;
            angleZ = angleZ / 1000.0;
            
            currentRotation = currentRotation - angleZ
            
            If ( currentRotation > 1.3 )
                currentRotation = 1.3
            Else If ( currentRotation < -1.3 )
                currentRotation = -1.3
            Else
                FindStrafe()                
                RotateAtPosition(angleZ,strafe)                                
            EndIf
            RotateAtPosition(angleY,up)
            
            MoveMouse ( middleX, middleY )
        EndIf
    EndMethod
    
    Method MoveCamera(distance# Var)
        FindDirection()
        position.x:+ (direction.x * distance)
        position.z:+ (direction.z * distance)
        target.x:+ (direction.x * distance)
        target.z:+ (direction.z * distance)
    EndMethod
    
    Method StrafeCamera(distance# Var)
        FindStrafe()
        position.x:+ (strafe.x * distance)
        position.z:+ (strafe.z * distance)
        target.x:+ (strafe.x * distance)
        target.z:+ (strafe.z * distance)
    EndMethod
    
    Method Look()
        gluLookAt(position.x, position.y, position.z, target.x, target.y, target.z, up.x, up.y, up.z)
    EndMethod
    
EndType

Code:
Import "settings.bmx"
Import "CRYVector.bmx"
Import "CRYCamera.bmx"

Global myCamera:CRYCamera = New CRYCamera

myCamera.position.y = 6
myCamera.target.y = 6
myCamera.target.z = 10
myCamera.up.y = 1

bglCreateContext width, height, 32, 60 | BGL_BACKBUFFER | BGL_DEPTHBUFFER

glMatrixMode GL_PROJECTION
glLoadIdentity
gluPerspective 45.0, ratio, .1, 5000

glMatrixMode GL_MODELVIEW
glLoadIdentity

glEnable GL_DEPTH_TEST
glEnable GL_POLYGON_SMOOTH
glEnable GL_LINE_SMOOTH
glEnable GL_POINT_SMOOTH

MoveMouse middleX, middleY

HideMouse

Repeat

    myCamera.MouseInput

    glClear GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
    glLoadIdentity

    myCamera.Look

    glBegin GL_QUADS
        glColor3f 1, 0, 0
        glVertex3f -10, 0, -10
        glVertex3f -10, 0, 10
        glVertex3f 10, 0, 10
        glVertex3f 10, 0, -10
    glEnd

    bglSwapBuffers

Until KeyDown ( key_escape )
Quote this message in a reply
Moderator
Posts: 529
Joined: 2003.03
Post: #2
Hiding the mouse does not work in Windowed mode.

You'd need to change target.y to make the camera look up or down, which you seem not to be doing.

Also Blitz's trig functions take degrees, not radians.

"Yes, well, that's the sort of blinkered, Philistine pig-ignorance I've come to expect from you non-creative garbage."
Quote this message in a reply
Sage
Posts: 1,066
Joined: 2004.07
Post: #3
I know that target.y is supposed to be changing. The main loop calls myCamera.MouseInput and that should call the rotation method which changes all three variables of target. Whether or not it is reassigning the variables correctly is an issue, I suppose.

Thanks for the hiding mouse info. I didn't know that.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  BlitzMax tutorial? dogone 4 5,990 Oct 3, 2008 09:15 PM
Last Post: stevejohnson
  blitzmax vs flash hertzcastle 1 3,525 Apr 3, 2008 04:38 PM
Last Post: OneSadCookie
  does blitzmax still support lua? rward 5 3,893 Apr 29, 2006 09:29 AM
Last Post: Leisure Suit Lurie
  drawtext in blitzmax Najdorf 2 3,708 Sep 21, 2005 06:06 AM
Last Post: unknown
  Fonts in Blitzmax? Yoda 3 3,733 Aug 1, 2005 11:45 AM
Last Post: Leisure Suit Lurie