Problem to implement an FPS camera like.

feanor91

02-08-2008 06:14:43

Hi

I try to implement a such behavior un VB Express 2008 and mogrenewt.

I follow examples found here, adapted to VB but it didn't work, apparently my cambody didn't move. Here my code :

First, variables :

'Déclarations pour Newton
Private myWorld As World 'Le monde physique
Private Gravity As Single = -9.8 'Et oui, on aura un poid...
Private CamSize As Vector3 = New Vector3(10, 10, 10) 'La taille de la caméra
Private CamNode As SceneNode 'Le node de la caméra
Private CamViewNode As SceneNode
Private CamBody As Body 'Le corps physique de la caméra
Private CamColl As CollisionPrimitives.Ellipsoid 'Le type de collision
Private NoMovement As Boolean = True


Second the callaback, and various functions (the callaback function seems never be called...:


Private Function get_body_position(ByVal bod As Body) As Vector3 'get the position of the body
Dim orient As Quaternion
Dim pos As Vector3

bod.GetPositionOrientation(pos, orient)

Return pos

End Function

Private Function get_body_orientation(ByVal bod As Body) As Quaternion ' get the orientation of the body {
Dim orient As Quaternion
Dim pos As Vector3

bod.GetPositionOrientation(pos, orient)

Return orient

End Function

Private Sub camera_force_callback(ByVal Corps As Body)

Dim masse As Single
Dim inertie As Vector3
Dim Force As Vector3

Corps.GetMassMatrix(masse, inertie)
Force = New Vector3(0, Gravity, 0)
Force *= masse

Corps.AddForce(Force)
'Corps.Omega = New Vector3(0, CameraRotationX, 0)

End Sub


Then my initNewton function (because I load an OSM Scene, so I seperate the 2 initialisation scene and newton :


Private Sub InitNewton()


'Initialisation de Newton pour la gestion des collision caméras, je n'y suis pas arrivé avec les RayScenQuery...
myWorld = New World 'le monde physique

Dim cam_size As Vector3 = New Vector3(10, 10, 10)
Dim cam_mass As Single = 40

'MogreNewt.Debugger.Instance.Init(mySceneManager)

'using the new "SceneParser" TreeCollision primitive. this will automatically parse an entire tree of
'SceneNodes (parsing all children), and add collision for all meshes in the tree.

Dim stat_col As MogreNewt.CollisionPrimitives.TreeCollisionSceneParser = New MogreNewt.CollisionPrimitives.TreeCollisionSceneParser(myWorld)
stat_col.ParseScene(mySceneManager.RootSceneNode, True)

Dim bod As MogreNewt.Body = New MogreNewt.Body(myWorld, stat_col)
stat_col.Dispose()
bod.AttachToNode(mySceneManager.RootSceneNode)
bod.SetPositionOrientation(New Vector3(0.0, 0.0, 0.0), Quaternion.IDENTITY)


'Collision of camera
CamNode = mySceneManager.RootSceneNode.CreateChildSceneNode("CamNode")
Me.CamNode.SetScale(Me.CamSize)
Me.CamColl = New CollisionPrimitives.Ellipsoid(myWorld, Me.CamSize)
Me.CamBody = New Body(myWorld, Me.CamColl)
Me.CamColl.Dispose()
Me.CamBody.AttachToNode(Me.CamNode)

Dim cam_inertia As Vector3 = MomentOfInertia.CalcEllipsoidSolid(cam_mass, cam_size)

Me.CamBody.SetMassMatrix(cam_mass, cam_inertia)
AddHandler Me.CamBody.ForceCallback, AddressOf camera_force_callback
Me.CamBody.AutoFreeze = False

'create an upvector. This forces the body to rotate just in the X and Z axes.
Dim uv2 As BasicJoints.UpVector = New BasicJoints.UpVector(myWorld, Me.CamBody, Vector3.UNIT_Y)

Me.CamViewNode = Me.CamNode.CreateChildSceneNode("CamViewNode", New Vector3(0, 5, 0))
'Me.CamViewNode.Position = mySceneManager.GetSceneNode(myCamera.Name).Position
mySceneManager.RootSceneNode.DetachObject(myCamera)
Me.CamViewNode.AttachObject(myCamera)
'myCamera.Position = New Vector3(0, -5, 0)
'Me.CamViewNode.Position = New Vector3(0, 0, 0)

End Sub


I dettach tne reattach camra because it's intialised by osmloader before.

And, finally, my movement, I do it in tumer because I don't use MOIS :


Private Sub timerRendu_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles timerRendu.Tick
'C'est ici que ce fait le rendu et différents évènements comme la gestion du clavier par exemple

Dim PasdeMouvement As Boolean = True

'on réinitilise les valeurs de mouvement
myTranslation.z = 0
myTranslation.x = 0
myTranslation.y = 0

'et on teste les touches.....

If GetAsyncKeyState(Keys.Up) Then
'myTranslation.z += -TRANSLATE
Dim dep As Vector3
dep.x = 0
dep.y = 1
dep.z = 0
Dim direction As Vector3 = get_body_orientation(CamBody) * Vector3.NEGATIVE_UNIT_Z
CamBody.Velocity = New Vector3(0, 20, 0) '(CamBody.Velocity * dep) + (direction * 30)
'CamBody.AddForce(New Vector3(10, 10, 10))
PasdeMouvement = False

End If

lblBodX.Text = CamBody.Position.x
lblBodY.Text = CamBody.Position.y
lblBodZ.Text = CamBody.Position.z

If GetAsyncKeyState(Keys.Down) Then
myTranslation.z += TRANSLATE
End If

If GetAsyncKeyState(Keys.Left) Then
myTranslation.x += -TRANSLATE
End If

If GetAsyncKeyState(Keys.Right) Then
myTranslation.x += TRANSLATE
End If

If GetAsyncKeyState(Keys.PageUp) Then
myTranslation.y += TRANSLATE
End If

If GetAsyncKeyState(Keys.PageDown) Then
myTranslation.y += -TRANSLATE
End If

'Et on déplace la caméra
myCamera.Position += myCamera.Orientation * myTranslation * timeSinceLastFrame

'Affichage des infos de rendu
Try

lblAvg.Text = "FPS moyennes: " & Mogre.StringConverter.ToString(MyWindow.AverageFPS, 3)
lblCurr.Text = "FPS courantes: " & Mogre.StringConverter.ToString(MyWindow.LastFPS, 3)
lblBest.Text = "Meilleures FPS: " & Mogre.StringConverter.ToString(MyWindow.BestFPS, 3)
lblWorst.Text = "Pires FPS: " & Mogre.StringConverter.ToString(MyWindow.WorstFPS, 3)
lblNumTris.Text = "Triangles: " & Mogre.StringConverter.ToString(MyWindow.TriangleCount)
lblNumBatches.Text = "Nombre de Batch: " & Mogre.StringConverter.ToString(MyWindow.BatchCount)
Catch ex As Exception

End Try

'et on rend une frame
myRoot.RenderOneFrame()

If SceneNodeSelected Is Nothing Then
'si un objet est sélectionné ou pas, on active ou désactive le panneau de paramètre
grpParamObjet.Enabled = False
cmdResetEtat.Enabled = False
Else
grpParamObjet.Enabled = True
cmdResetEtat.Enabled = True
End If

End Sub


When I press Up arrow, I have no movement at all...What I did wrong?

And finaly, you can find all my project here :

http://rapidshare.com/files/134230788/o ... n.rar.html


I put an osm scene to view in Kites directory. Just a word about project, it is an simple oFusion scene viewer that I wrote as my first ogre project to test functionality that I will need in another project. By now, I manage to do all I want, exept detection collision with cam.
And therefore, I will post it somewhere to help people to understand how to implement ogre in vb .net, because, by now, i found there is so few (well, i found nothing) example in VB.

I someone can help me, it will be great.


Best regards.

feanor91

03-08-2008 20:56:45

Hi

Well, I found something, I add myWorld.Update(step) ine my timer update...So, now, my camera move by 113 units, on X oy Z, but no more....when reaching 113 units on either axes, the callback function cease to be called and my camera stop...I cant move backward or left ou forwaard or right, in fact myworld.update cease to work....

Why?

A clue? If I multiply mu cam size by 10 (passing it to 1000), I multyply mu movement by about 2 (200 units) but the symptom are the same, all stop....

I'm suck!

dudeabot

04-08-2008 00:46:57

probably you need to set your world size bigger

walaber

04-08-2008 00:53:45

yup. set the world size on the OgreNewt::World object to the actual size of your simulation world.

feanor91

04-08-2008 07:17:21

Oh! Well! It works, thansk a lot....But my camera is a ghost, it pass through all my objects, it's not the beahviour that I want to achieve, there is not complete example somewhere on how to implement this? I found, there is a lack of documentation about ogre, newton, and all that things, evenn the wiki are empty. It's not simple for new user, and even if api are documented, no examples shows how to use it.

feanor91

04-08-2008 11:57:39

Oh! Well! It works, thansk a lot....But my camera is a ghost, it pass through all my objects, it's not the beahviour that I want to achieve, there is not complete example somewhere on how to implement this? I found, there is a lack of documentation about ogre, newton, and all that things, evenn the wiki are empty. It's not simple for new user, and even if api are documented, no examples shows how to use it.

Uh....Well, the problem is more complicated than that...I manage to found an example wote in C++ and to study it. A chance, it's based on an osm scene so I can load it into my viewer. And guess what? It works under my program, very well, collision detection are active, all works fine, but, when I load my scene, detection collision aren't active but all the code is the same, the only difference is in the scene....Any kind of idea? I swim hard on this!

dudeabot

04-08-2008 14:47:30

when you load the scene are you placing collision for your ma, entities etc?

also if you are using the ogrenewt framelistener you might find useful to see the debug lines (F3)

feanor91

04-08-2008 16:03:15

when you load the scene are you placing collision for your ma, entities etc?

also if you are using the ogrenewt framelistener you might find useful to see the debug lines (F3)


As you can see in my code, i use newton scene parser....with optimize on. If I put optimize off, my scene is weel parsed and I have collision detection, but only on my wall, and not on other object in the scene...;If I turn debug on, debug lines appears on all my object, but when cam colide with them, it passes through...

Another problem is when I rotate my cam witj mouse, my deplacement did'nt follow my rotation, i move always on world axes and not on cam axes.

And another thing is that sometimes, my cam start to rotate like a fool and didn't stop as if I had apply some torque on it, but I never do that..

It's very hard to understand, but step by step I manage to advance, by digging deeper and deeper in forum, and picking something here and other thing elsewhere...When I will manage to finish my work I'l give it to community hoping that it will help guys like me.

meanwhile, many thanks for help.

dudeabot

05-08-2008 09:01:39

im not sure what is causing it

but i usually do



Dim direction As Vector3 = get_body_orientation(CamBody) * Vector3.NEGATIVE_UNIT_Z
CamBody.Velocity = New Vector3(0, 20, 0) '(CamBody.Velocity * dep) + (direction * 30)
'CamBody.AddForce(New Vector3(10, 10, 10))
PasdeMouvement = False

End If


int the force callback

feanor91

05-08-2008 10:26:19

Hi

Well, I make a step further today.

In the force callback function, I add :

Corps.Omega = New Vector3(0, 0, 0)

And, it stops camera foolish rotation when I hit things.

Then, I change creation of camnode and camview node in InitNewton function, and now, collision detection is made for all my things.

A pretty good news, but (there always a but) when my scene is loaded, my camear position is set at 0,5,0 and not at my real cam position as fixed in my
osm scene...Here my new initnewton func :


Private Sub InitNewton()


'Initialisation de Newton pour la gestion des collision caméras, je n'y suis pas arrivé avec les RayScenQuery...
myWorld = New World 'le monde physique
myWorld.SetWorldSize(New Vector3(-100000, -100000, -100000), New Vector3(100000, 100000, 100000))

Dim cam_size As Vector3 = New Vector3(10, 10, 10)
Dim cam_mass As Single = 40


'Création du monde physique pour Newton

Dim stat_col As MogreNewt.CollisionPrimitives.TreeCollisionSceneParser = New MogreNewt.CollisionPrimitives.TreeCollisionSceneParser(myWorld)
stat_col.ParseScene(mySceneManager.RootSceneNode, False) 'Utilisation du parser de scène Newton, attention, à ce jour (juillet 2008), le parmètre true, au mieux, ne fonctionne pas et au pire plante le programme.

'Création et paramétrage du body pour le monde
Dim bod As MogreNewt.Body = New MogreNewt.Body(myWorld, stat_col)
stat_col.Dispose()
bod.AttachToNode(mySceneManager.RootSceneNode)
bod.SetPositionOrientation(New Vector3(0.0, 0.0, 0.0), Quaternion.IDENTITY)

'Collision de la caméra
Dim PosCam As Vector3 = mySceneManager.GetSceneNode(myCamera.Name).Position 'on récupère la position de la caméra
CamNode = mySceneManager.RootSceneNode.CreateChildSceneNode("CamNode", PosCam) 'on crè un Scennode à la position de la caméra
Me.CamNode.SetScale(Me.CamSize) 'on le met à la taille de la caméra
Me.CamColl = New CollisionPrimitives.Ellipsoid(myWorld, Me.CamSize) 'on crè le système de collision
Me.CamBody = New Body(myWorld, Me.CamColl) 'on l'applique au body représentant la caméra
Me.CamColl.Dispose() 'on libère la collision
Me.CamBody.AttachToNode(Me.CamNode) 'et on l'attache au noeud créé précédement

'calcul de l'inertie de la caméra
Dim cam_inertia As Vector3 = MomentOfInertia.CalcEllipsoidSolid(cam_mass, cam_size)
Me.CamBody.SetMassMatrix(cam_mass, cam_inertia)
AddHandler Me.CamBody.ForceCallback, AddressOf camera_force_callback 'la fonction appelée lors de l'update du monde physique
Me.CamBody.AutoFreeze = False 'Important, sinon, iompossible de déplacer le body...

'Création d'un "UP Vector" pour empé cher le body de tourner sur Y
Dim uv2 As BasicJoints.UpVector = New BasicJoints.UpVector(myWorld, Me.CamBody, Vector3.UNIT_Y)

'Création d'un scenenode 5 unités au dessus du camnode pour y mettre la caméra
Me.CamViewNode = Me.CamNode.CreateChildSceneNode("CamViewNode", New Vector3(0, 5, 0)) 'création du scenenode
mySceneManager.RootSceneNode.DetachObject(myCamera) 'on détache la caméra du rootscenenode (créé par OSMLoader)
Me.CamViewNode.AttachObject(myCamera) 'et on attache la caméra au viewnode

CamBody.MaterialGroupID = New MogreNewt.MaterialID(myWorld) 'on y affecte un material

'CamNode.ResetToInitialState() 'obligatoire pour que la caméra soit bien positionnée à ses coordonnées
MogreNewt.Debugger.Instance.Init(mySceneManager) 'et on initialise le debugger newton.

End Sub


As you see, I achive to create my camnode at my cam position, if I look at properties of the node, I have the good ccordinates in the position vector, but my cam is set to (0,5,0) ie the position of the camviewnode that is a childnode of camnode....I swim, I swim, but by swiming, I finnaly advance ;o)

Just another thing, how, damnit, can I do to rotate axes when rotating camera! I see in example that yaw and pitch are applied to viewnode, I do the same, but it doesn't work, when I hit key up, i advance always on -Z world axes and not on -Z cam axes for example....here my mousemove func :


Private Sub picMogre_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles picMogre.MouseMove

'Si le bouton gauche est cliqué, on tourne la caméra
If e.Button = Windows.Forms.MouseButtons.Left Then
If xOrig - e.X <> 0 Then 'déplacement horizontal
If xOrig - e.X < 0 Then 'souris déplacée vers la droite
'myCamera.Yaw(-ROTATE * timeSinceLastFrame)
CamViewNode.Yaw(-ROTATE * timeSinceLastFrame)
Else
'myCamera.Yaw(ROTATE * timeSinceLastFrame)
CamViewNode.Yaw(ROTATE * timeSinceLastFrame)
End If
End If
If yOrig - e.Y <> 0 Then 'déplacement vertical
If yOrig - e.Y < 0 Then 'souris déplacée vers le bas
'myCamera.Pitch(-ROTATE * timeSinceLastFrame)
CamViewNode.Pitch(-ROTATE * timeSinceLastFrame)
Else
'myCamera.Pitch(ROTATE * timeSinceLastFrame)
CamViewNode.Pitch(ROTATE * timeSinceLastFrame)
End If
End If
ElseIf e.Button = Windows.Forms.MouseButtons.Right Then 'on zoom/dézoom
If yOrig - e.Y <> 0 Then
If myCamera.FOVy.ValueRadians + ((e.Y - yOrig) * timeSinceLastFrame) >= 0 And myCamera.FOVy.ValueRadians + ((yOrig - e.Y) * timeSinceLastFrame) <= 3 Then
myCamera.FOVy = myCamera.FOVy.ValueRadians + ((e.Y - yOrig) * timeSinceLastFrame)
End If
End If
txtFOV.Text = myCamera.FOVy.ValueRadians
ElseIf e.Button = Windows.Forms.MouseButtons.Middle Then 'on fait rouler la caméra
If xOrig - e.X <> 0 Then
If xOrig - e.X < 0 Then
myCamera.Roll(-ROTATE * timeSinceLastFrame)
Else
myCamera.Roll(ROTATE * timeSinceLastFrame)
End If
End If
End If

'et on récupère les valeurs courantes de position pour les futurs calculs.
xOrig = e.X
yOrig = e.Y


End Sub

feanor91

05-08-2008 10:55:00

Just one thing I want to understand :
why creating a scenenode, then attaching body to it, then creating a camviennode child of scenenode then attaching camera to it? I did not understand why doing this.

Edit : OK I manage to position my cam as this :

CamBody.SetPositionOrientation(PosCam, OrientCam)



It works fine, en plus I have a funny effect when my scene initialize, the cam rotate down up to orientcam.

Well, by now, all is almost perfect, just fixing this damn thing with axes and I will be glad.