April 12, 2018 at 11:42 pm #14328
How do I get hold of the world position of a mesh’s vertex? I’m trying to visualise a terrain’s vertices, and have got my mesh vertices easily enough, but it’s just the ‘raw’ mesh vertices rather than their current position in space…
See DrawVertices:Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163[crayon-5b54486997011352946098 inline="true" ]#Import "<std>"#Import "<mojo3d>"Using std..Using mojo..Using mojo3d..' ----------------------------------------' Application name...' ----------------------------------------Global AppName:String = "My 3D Game"Class Model ExtensionMethod DrawVertices:Void (canvas:Canvas, from_camera:Camera)For Local v:Vertex3f = Eachin Mesh.GetVertices ()Local v2:Vec2f = from_camera.ProjectToViewport (v.position)canvas.DrawRect (v2.x, v2.y, 1, 1)NextEndEndClass Game Extends WindowConst SHIFT_BOOST:Float = 5.0Field camera_boost:Float = 1.0' Basic 3D scene requirements...Field scene:SceneField camera:CameraField light:Light' Test cube...Field cube:ModelField cubemesh:MeshField cubematerial:MaterialMethod New (title:String, width:Int, height:Int, flags:WindowFlags)Super.New (title, width, height, flags)scene = Scene.GetCurrent () ' Important!camera = New Camera' Camera settings...camera.Near = 0.1' Camera position...camera.Move (0, 0, -2)camera.Rotate (0, 0, 0)light = New Lightlight.Move (-10, 10, -10)light.Rotate (0, 0, 0)cubemesh = Mesh.CreateBox (New Boxf (-0.5, -0.5, -0.5, 0.5, 0.5, 0.5)) ' 1 x 1 x 1cubematerial = New PbrMaterial (Color.Aluminum)cube = New Model (cubemesh, cubematerial)cube.Rotate (0, 45, 0)EndMethod UpdateGame:Void ()EndMethod OnRender (canvas:Canvas) OverrideProcessInput ()UpdateGame ()cube.Rotate (0.0, 1.0, 0.0)' Tell app to draw frame when ready...RequestRender ()' Render scene to canvas (passed to OnRender by mojo), from camera...scene.Render (canvas)cube.DrawVertices (canvas, camera)EndMethod ProcessInput:Void ()If Keyboard.KeyHit (Key.Space) Then light.CastsShadow = Not light.CastsShadowIf Keyboard.KeyDown (Key.LeftShift)camera_boost = SHIFT_BOOSTElsecamera_boost = 1.0EndifIf Keyboard.KeyHit (Key.Escape) Then App.Terminate ()If Keyboard.KeyDown (Key.A)camera.Move (0.0, 0.0, 0.1 * camera_boost)EndifIf Keyboard.KeyDown (Key.Z)camera.Move (0.0, 0.0, -0.1 * camera_boost)EndifIf Keyboard.KeyDown (Key.Left)camera.Rotate (0.0, 1.0, 0.0)EndifIf Keyboard.KeyDown (Key.Right)camera.Rotate (0.0, -1.0, 0.0)EndifIf Keyboard.KeyDown (Key.Up)camera.Rotate (1.0, 0.0, 0.0, True)EndifIf Keyboard.KeyDown (Key.Down)camera.Rotate (-1.0, 0.0, 0.0, true)EndifEndEndFunction Main ()' Windowed mode...Local width:Int = 640Local height:Int = 480Local flags:WindowFlags = WindowFlags.Center' Full-screen mode (comment out above)...' Local width:Int = 1920' Local height:Int = 1080' Local flags:WindowFlags = WindowFlags.FullscreenNew AppInstanceNew Game (AppName, width, height, flags)App.Run ()EndApril 13, 2018 at 4:45 am #14330
Use something like entity.Matrix * vertex.position, eg:Monkey1Local v2:Vec2f = from_camera.ProjectToViewport( Self.Matrix * v.position )
The matrix multiplication transforms the Vec3f position from one coord space (ie: local space) to another (ie: world space).
To get from world space to local space instead, use the inverse matrix, eg: -entity.Matrix * worldPos.April 13, 2018 at 7:27 am #14341
Thanks, Mark, that looks to have done it… handy to know it was that simple!April 13, 2018 at 9:22 am #14342
The other usefull thing to know here is how multiplying matrices has the effect of ‘chaining’ a sequence of transforms together.
So say you’ve got 2 entities, and a point in local space of one of the entities, and you want to transform it into the local space of the other entity, you can do something like -entity2.Matrix * entity1.Matrix * point. This will transform a point from entity2’s local space to entity1’s local space. Note that matrix multiplication is not commutative (eg: matrix1*matrix2 is not the same as matrix2*matrix1) although it is associative (eg: (matrix1*matrix2)*matrix3 is the same as matrix1*(matrix2*matrix3)) and should generally be read ‘right to left’ (eg: the above first transforms point by entity1.Matrix and then by -entity2.Matrix). So by precalculating matrices like this, you can actually store a complex sequence of transforms in a singe matrix. This is what those weird sounding matrices like ‘ModelViewProjectionMatrix’ are actually doing, transforming from model space to view space to ‘clip’ space (another topic!)…
And that’s it – that’s most of what I know about 3d!April 13, 2018 at 12:40 pm #14346
Cool, thanks, have saved that for reference, will try grasp it, or as much as I need when I need it!
I have stumbled across ModelViewProjectionMatrix and the like in GLSL fragment shaders, something I’ll be dabbling in again soon, and I realised earlier that this vertex drawing is probably a good candidate for shader-ising anyway.
Got my terrain vertex drawing working for now, slow as heck (obviously), but this might actually help me narrow it down within a given range and speed up slightly.
At least I can see where the vertices are in relation to my texture, which is what I was after!
You must be logged in to reply to this topic.