About Monkey 2 › Forums › Monkey 2 Programming Help › How does AddVertices work?
Tagged: AddVertices, mesh, model, triangles
This topic contains 4 replies, has 3 voices, and was last updated by
DruggedBunny
1 year, 3 months ago.
-
AuthorPosts
-
December 29, 2017 at 5:16 pm #12499
I’m attempting to build my own meshes, but I can only get the first triangle to show up.
If you comment out the first call to AddMesh (around line 112, below) the second triangle is correctly shown, but with the first call in place, the second triangle doesn’t appear:
Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184#Import "<std>"#Import "<mojo3d>"Using std..Using mojo..Using mojo3d..Global AppName:String = "My 3D Game"Function CreateTri:Mesh (x0:Float = -0.5, y0:Float = 0.5, z0:Float = 0.0, x1:Float = 0.5, y1:Float = -0.5, z1:Float = 0.0, x2:Float = -0.5, y2:Float = -0.5, z2:Float = 0.0)Local verts:Vertex3f [] = New Vertex3f [3]verts [0].position = New Vec3f (x0, y0, z0)verts [1].position = New Vec3f (x1, y1, z1)verts [2].position = New Vec3f (x2, y2, z2)Local indices:UInt [] = New UInt [3]indices [0] = 0indices [1] = 1indices [2] = 2Local mesh:Mesh = New Mesh (verts, indices)Return meshEndFunction AddMesh:Void (model:Model, mesh:Mesh, material:PbrMaterial = Null)If Not materialmaterial = New PbrMaterial (Color.Grey)EndifIf Not model.Meshmodel.Mesh = meshElse' Assuming just new mesh vertices needed (ie. ADDS to current verts)...' model is the model being added to...model.Mesh.AddVertices (mesh.GetVertices ())' Local verts:Vertex3f[]' Local v:Vertex3f' Current mesh vertices (testing if needed as well as new verts!)...' For v = Eachin model.Mesh.GetVertices()' verts = verts.Resize (verts.Length + 1)' verts [verts.Length - 1] = v' Next' Passed-in new mesh from which to add vertices...' For v = Eachin mesh.GetVertices()' verts = verts.Resize (verts.Length + 1)' verts [verts.Length - 1] = v' Next' model.Mesh.AddVertices (verts)Endif' Needed??If Not model.Material Then model.Material = material' Needed??model.Mesh.UpdateNormals ()model.Mesh.UpdateTangents ()EndClass Game Extends WindowConst SHIFT_BOOST:Float = 5.0Field camera_boost:Float = 1.0Field scene:SceneField camera:CameraField light:LightField land:ModelMethod New (title:String, width:Int, height:Int, flags:WindowFlags)Super.New (title, width, height, flags)scene = Scene.GetCurrent ()camera = New Cameracamera.Near = 0.1camera.Move (0, 0, -2)camera.Rotate (0, 0, 0)light = New Lightlight.Move (-10, 10, -10)land = New Model' Add new triangles to land model's mesh...AddMesh (land, CreateTri ()) ' Defaults to (-0.5, 0.5, 0.0, 0.5, -0.5, 0.0, -0.5, -0.5, 0.0)AddMesh (land, CreateTri (-0.5, 0.5, 0.0, 0.5, 0.5, 0.0, 0.5, -0.5, 0.0))light.PointAt (land)EndMethod UpdateGame:Void ()EndMethod OnRender (canvas:Canvas) OverrideProcessInput ()UpdateGame ()RequestRender ()scene.Render (canvas, camera)EndMethod ProcessInput:Void ()If 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 ()Local width:Int = 1024Local height:Int = 768Local flags:WindowFlags = WindowFlags.CenterNew AppInstanceNew Game (AppName, width, height, flags)App.Run ()EndWondered if AddVertices needed ALL vertices (both current mesh verts PLUS the new ones), but that didn’t work either — see commented-out attempt in AddMesh.
By way of explanation, AddMesh takes an existing Model, a new Mesh (received from CreateTriangle) and in theory adds the vertices from that new Mesh to the existing Model, though I don’t know if this is correct/appropriate.
Also not sure if I should be using UpdateNormals, etc… ?
December 29, 2017 at 7:48 pm #12505Mark added a banana that showed how to create a quad mesh. I asked for a example back then. I made several more examples that I have on my monkey2-3d github.
https://github.com/Pakz001/Monkey2-3D
December 29, 2017 at 11:05 pm #12517I was actually looking closely at those earlier, Pakz, but a search suggested AddVertices wasn’t part of it — I’m basically trying to add vertices to an existing mesh that I’ve created, rather than create all vertices in one go, which I think all of your samples do.
December 30, 2017 at 3:57 am #12521You need to AddTriangles too – all meshes are currently indexed so you will need to add the triangle indices for any newly added vertices.
In this though, simply going “model.Mesh.AddTriangles (mesh.GetIndices() )” wont work because you’ll just be adding the same [0,1,2], you’ll need to be trickier.
[edit]I just added AddMesh and it appears to work, ie: instead of addVertices use: model.Mesh.AddMesh( mesh ) which will add vertices and ‘relocated’ indices – draws a quad here anyway.
You’ll have to be a bit cleverer with the model.Materials array too – you’ll need to ‘grow’ this for each added material, in fact maybe it should just be a stack?
Anyway, here’re my tweaks:
Monkey12345678910111213141516171819202122232425Function AddMesh:Void (model:Model, mesh:Mesh, material:PbrMaterial = Null)If Not materialmaterial = New PbrMaterial (New Color( Rnd(),Rnd(),Rnd() ))EndifIf Not model.Meshmodel.Mesh = meshmodel.Materials=New Material[]( material )Elsemodel.Mesh.AddMesh( mesh,model.Mesh.NumMaterials )Local materials:=model.Materials.Resize( model.Materials.Length+1 )materials[materials.Length-1]=materialmodel.Materials=materialsEndifmodel.Mesh.UpdateNormals ()model.Mesh.UpdateTangents ()EndThe future of Model.Material is still up in the air, I may yet rip it out and just leave Model.Materials.
UpdateNormals/Tangents aren’t really needed as AddMesh doesn’t merge vertices so it wont affect existing normals/tangents. Eventually though, there’ll probably be an Optimize() method that will merge vertices and you’ll need to update normals/tangents after that.
Note the Mesh class is really designed for ‘offline’ stuff. In realtime, it’ll be much faster to directly use VertexBuffers and IndexBuffers and to override OnRender.
December 30, 2017 at 4:16 pm #12528Thanks, Mark, that’ll do me!
Yeah, I’ve yet to try and grasp materials, but the Material/Materials[] thing is confusing, and I’d thought iterating through Materials[] would be needed to do things properly.
Perhaps Materials[0] could be used as the default and then overridden by the user as they see fit?
Yeah, something that optionally merges vertices would be good.
Not got anywhere near VertexBuffers and co yet! This’ll let me get started on building things myself, then I’ll no doubt move on and try get vertex buffers and co…
-
AuthorPosts
You must be logged in to reply to this topic.