Learning the 3D world and Matrix manipulation.

Hi folks.

This is a plea from a very confused old man who has become completely unstuck with Matrices and the 3D world. I’m ok getting to the shops, it’s just the code side of things I’m having problems with!

I’ve been looking for online monogame examples which I’m personally finding quite difficult, (maybe I’m just a bit dim!), they either assume a mathematical knowledge of Matrices, or give helpful text such as “Now let’s add the rotation function…” followed by 30 lines of code which aren’t very well documented.

I’ve got most of the 2D stuff assimilated, so mostly I know what I’m doing, I’m just completely new to the 3D world. Could someone please point me in the direction of some documentation that includes code examples and assumes the reader is a complete idiot?

Many thanks.

Here’s a couple links.
In the second link at the bottom is a class i posted that might be helpful codewise.

http://www.codinglabs.net/article_world_view_projection_matrix.aspx

http://www.monogame.net/documentation/?page=T_Microsoft_Xna_Framework_Matrix

Very good point Will, I have no idea what you’re actually talking about but I’m sure I’ll come across it soon, so thank you for bringing it up.

Sorry if that is too much, those two links have to do with matrix’s and 3d.
What are you having trouble with or trying to understand currently?

Sorry, I miss read your post, I thought someone else had asked another question, but all good, and still applies.

So I’ve read up on the first article you suggested and things do make more sense, and when I go back to look at the code I can see all it’s really doing is A=BCD. If I’d known that before I’d started things would have clicked a bit sooner. I should have studied the syntax closer rather than panicking!

I’ve managed to put a ‘meteor’ on screen, I can rotate it, move it and scale it. Lovely. So I thought I’d create a List Of and make a 100 meteors, all with random locations and make sure the principals transferred easily to multiple objects. All the code does is loop the list and change an x, y or z axis of the position vector3.

But all of the objects are drawing on top of each other so it only looks like there is one object. I know they’re all drawing as if I make the number 10000 meteors it starts to lag.

I’m 100% sure (give or take a percent) that my calculations are correct and I’m not overwriting every object with the same locations. In fact I am absolutely positive. So I’m wondering if it’s anything to do with the View and Camera matrices, but the drawing code looks good too.

But I can’t see any reason why every object would draw on top of each other so maybe it my code, although it couldn’t be simpler.

If I can’t get it working in a couple of hours I’ll post what I’m doing.

Thanks Will.

I have just proved by DrawString’ing the positions of all the objects they are all being drawn and they all have different positions, but they’re all being drawn in the same place.

My update/draw code follows. Sorry for not using the ‘insert code’ button, I’m having real problems with it.
Yes, every object is definitely starting in a random location.
Yes, the update routine is correctly adjusting the object locations.
The GameObject class only holds variables, no calculations.

Protected Overrides Sub Update(gameTime As GameTime)
If Keyboard.GetState.IsKeyDown(Keys.Right) Then
For Each m As GameObject In Meteors
m.PositionX -= CSng(MoveIncrement)
Next
End If

For Each m As GameObject In Meteors
      ApplyEverything(m)
Next
MyBase.Update(gameTime)

End Sub

Private Sub ApplyTranslation(o As GameObject)
WorldMatrix = Matrix.CreateTranslation(o.Position)
End Sub

Protected Overrides Sub Draw(gameTime As GameTime
GraphicsDevice.Clear(Color.Black)
For Each m As GameObject In Meteors
DrawModel(m)
Next
MyBase.Draw(gameTime)
End Sub

Private Sub DrawModel(o As GameObject)
For Each Mesh As ModelMesh In o.ObjectModel.Meshes
For Each Effect As BasicEffect In Mesh.Effects

        Effect.EnableDefaultLighting()
        Effect.LightingEnabled = True

        Effect.AmbientLightColor = New Vector3(1, 0, 0)
        Effect.View = ViewMatrix
        Effect.World = WorldMatrix
        Effect.Projection = ProjectionMatrix

    Next
    Mesh.Draw()
Next

End Sub

Sometimes you have to click the code tag with your code highlighted a couple times to get it to line up right.

Im not surprised your having trouble finding examples it looks like your using visual basic.net most everyone here is using c#. Most all the example code you find will be in c# as well as all the tutorials.

Protected Overrides Sub Update(gameTime As GameTime)
    If Keyboard.GetState.IsKeyDown(Keys.Right) Then
        For Each m As GameObject In Meteors
            m.PositionX -= CSng(MoveIncrement)
        Next
    End If

For Each m As GameObject In Meteors
      ApplyEverything(m)
Next
MyBase.Update(gameTime)

End Sub

Private Sub ApplyTranslation(o As GameObject)
  WorldMatrix = Matrix.CreateTranslation(o.Position)
End Sub

Protected Overrides Sub Draw(gameTime As GameTime  
    GraphicsDevice.Clear(Color.Black)
    For Each m As GameObject In Meteors
        DrawModel(m)
    Next
    MyBase.Draw(gameTime)
End Sub

Private Sub DrawModel(o As GameObject)
    For Each Mesh As ModelMesh In o.ObjectModel.Meshes
        For Each Effect As BasicEffect In Mesh.Effects

        Effect.EnableDefaultLighting()
        Effect.LightingEnabled = True

        Effect.AmbientLightColor = New Vector3(1, 0, 0)
        Effect.View = ViewMatrix
        Effect.World = WorldMatrix
        Effect.Projection = ProjectionMatrix

    Next
    Mesh.Draw()
Next

End Sub

Well its not all that different to c# anyways, though i don’t use it.

It appears ok from this code. The only thing i can think of from whats shown above is maybe.
.
Does this function CSng actually return a different random number for each object or just a new random number that only changes each time the button is pressed ?

If Keyboard.GetState.IsKeyDown(Keys.Right) Then
For Each m As GameObject In Meteors
// the below looks suspect.
// ? if the below were to return the same value in the loop that would put everything in the same place.
// is there a Randomize() call in that function CSng ? shouldn't this be a assignment for testing purposes.
m.PositionX -= CSng(MoveIncrement)

I know what you mean, but all the objects have a different start location as set in the initialise routine, within the loop that creates the list the x, y and z values of their starting position vector3 are randomised from 1 to 10. Whilst grasping I added some debug text to the screen, all the position vectors are indeed different and working correctly with the translation, just not drawing.

With some further testing I’ve worked out only the last object is actually being drawn, which makes me wonder if there is something in the draw routines that are overwriting the previous object, but as I don’t know, I can’t say I know, if you know what I mean!

Yeah, there aren’t many of us working in VB, I’m far too long in the tooth (and too addled with gin) to start learning another language, but I can transpose c# pretty easily. I just hate all the curly brackets! I’m saddened there wasn’t a VB template added to 3.6.

Do let me know if you can see anything incorrect with the drawing routines. What I really need is a simple sample drawing multiple objects, I find it the easiest way to pick things up. I’m not asking you to write anything, but if you know of any samples anywhere do let me know. :slight_smile:

Sorry i didn’t have a lot of time too look at it the other day i should of noticed before though.

I think i see whats going on.

You have a world matrix variable your applying translations to by a function but that’s just a struct of game class (scope)

Private Sub ApplyTranslation(o As GameObject)
  WorldMatrix = Matrix.CreateTranslation(o.Position)
End Sub

In your current code when it looped it looks like it would just keep updating this game class scoped variable worldmatrix so it would just be over writing that and the last setting in the loop would stick.

Each object should have its own world matrix that is set by ApplyTranslation.
Something like so.

o.WorldMatrix = Matrix.CreateTranslation(o.Position);

When you draw your using that same worldmatrix to set to the basic effect.

Effect.World = WorldMatrix

If you were to print out WorldMatrix.M41 .M42 and .M43 from within the draw function directly below that line they would probably be all the same numbers for the x y z postions.

Each draw call should however be using a world matrix specific to the object.
So it should look something like so in your draw call.

Effect.World = o.WorldMatrix

Hi Will. I woke up this morning realising what a numpty I’ve been. There I am happily overwriting the same matrix time and time again. Then drawing the last compute 100 times.

If I had a job that was more dangerous I’d be very dangerous!

Thank you so much for your recent help, with this out of the way I’m sure I’ll go on to write some truly awful games!

Cheers.