Download presentation
Presentation is loading. Please wait.
Published byAustin Silas Gaines Modified over 8 years ago
1
1 Manage Mesh Data Chapter 8
2
2 How to manage Mesh data The most important two objects of mesh are VertexBuffer and IndexBuffer, which can obtained by code: Mesh mesh; VertexBuffer VB = mesh.VertexBuffer; IndexBuffer IB = mesh.IndexBuffer; We can use them to set vertex data and index in a mesh. Also we can partially change the data in a mesh. The other two important mesh values are number of vertices and number of faces ; int Total_Vertex = mesh.NumberVertices ; int Total_Faces = mesh.NumberFaces ;
3
3 Mesh Constructor public Mesh( int numFaces, int numVertices, MeshFlags options, VertexFormats vertexFormat, Device device ); We need to set IndexBuffer for Mesh object also.
4
4 Get Mesh vertices Vertices of mesh can got by code Mesh meshTeapot = Mesh.Teapot(device); VertexBuffer VB = meshTeapot.VertexBuffer; int total = meshTeapot.NumberVertices ; CustomVertex.PositionNormal [] verts = new CustomVertex.PositionNormal[total]; verts = ( CustomVertex.PositionNormal[]) VB.Lock(0, typeof(CustomVertex.PositionNormal), LockFlags.None, total); VB.Unlock();
5
5 Get Mesh Indices Indices of mesh can got by code Mesh meshTeapot = Mesh.Teapot(device); IndexBuffer IB = meshTeapot.IndexBuffer; int totalFace = meshTeapot.NumberFaces ; short [] indices = null; indices= (short[])IB.Lock(0, 3*totalFace, LockFlags.None); IB.Unlock();
6
6 Interpolation meshes We have three given Dolphin meshes. If we want make an animation of dolphin swimming, those 3 meshes would not be enough for drawing. Therefore, we need to make several middle position meshes, which can be obtained by programs.
7
7 Make middle position vectors Having two vectors V0 & V1, we want to fine the middle position V for 0 1. V0 VV V5 When is changing from 0 to 1, V will be changing from V0 to V1 linearly.
8
8 Declare Structure & Variables struct DolphinVertex { public Vector3 Position; public Vector3 Normal; } Mesh DolphinMesh = null; DolphinVertex[] verts0; DolphinVertex[] verts1; DolphinVertex[] verts2; Those 3 vertex array are from three meshes. The vertex of DolphinMesh is change dynamically.
9
9 Create mesh vertices private void InitMesh() { ExtendedMaterial[] materials = null; Mesh mesh0 = Mesh.FromFile("Dolphin1.x", MeshFlags.SystemMemory, device, out materials); Mesh mesh1 = Mesh.FromFile("Dolphin2.x", MeshFlags.SystemMemory, device); Mesh mesh2 = Mesh.FromFile("Dolphin3.x", MeshFlags.SystemMemory, device); meshMaterial = materials[0].Material3D; meshMaterial.Ambient = meshMaterial.Diffuse; DolphinMesh = mesh0.Clone(MeshFlags.Managed, mesh0.VertexFormat, device); int total = mesh0.NumberVertices ;
10
10 VertexBuffer VB0 = mesh0.VertexBuffer; VertexBuffer VB1 = mesh1.VertexBuffer; VertexBuffer VB2 = mesh2.VertexBuffer; verts0 = (DolphinVertex[])VB0.Lock(0, typeof(DolphinVertex), LockFlags.None, total); verts1 = (DolphinVertex[])VB1.Lock(0, typeof(DolphinVertex), LockFlags.None, total); verts2 = (DolphinVertex[])VB2.Lock(0, typeof(DolphinVertex), LockFlags.None, total); VB0.Unlock();VB1.Unlock();VB2.Unlock(); VB0.Dispose();VB1.Dispose();VB2.Dispose(); mesh0.Dispose(); mesh1.Dispose(); mesh2.Dispose(); }
11
11 private void SetDolphin(float alpha) { VertexBuffer VB = DolphinMesh.VertexBuffer; int total = DolphinMesh.NumberVertices ; DolphinVertex[] verts =(DolphinVertex[])VB.Lock(0, typeof(DolphinVertex), LockFlags.None, total); for(int i=0; i<total; i++) { float t = (float)Math.Abs(alpha); if(alpha>0){ verts[i].Position =t*verts0[i].Position+ (1f-t)*verts1[i].Position; verts[i].Normal =t*verts0[i].Normal + (1f-t)*verts1[i].Normal ; } else{ verts[i].Position =t*verts2[i].Position+ (1f-t)*verts1[i].Position; verts[i].Normal =t*verts2[i].Normal + (1f-t)*verts1[i].Normal ; } VB.Unlock(); }
12
12 Control the animation rate void Render() {.... float alpha = (float)Environment.TickCount/500.0f; // 0.5 second one unit SetDolphin((float)Math.Sin(alpha)); // one period is 2pi unit = pi/2 sencods is about 1.57 seconds DolphinMesh.DrawSubset(0);.... }
13
13 Set the swimming path The swimming path is ellipse, whose equation is 20 5 Z X Here we set t = Environment.TickCount/3000f; which is 3 seconds one unit. So 2 is about 6 seconds. Also the dolphin head needs to follow the tangent direction. However, we approximately use RotationY(t). At last we want add dolphin head nodding behavior, which make swimming looks like real
14
14 private void SetSwimmingPath() { float t= (float)Environment.TickCount/3000f; // 3 seconds one unit Matrix matS= Matrix.Scaling(0.01f, 0.01f, 0.01f); Matrix matT= Matrix.Translation(-5*(float)Math.Sin(t), (float)Math.Sin(6*t)/2, 10-10*(float)Math.Cos(t)); // swimming along an ellipse, In y direction add curving Matrix matRZ= Matrix.RotationZ(-(float)Math.Cos(6*t)/6); // head will be up and down nodding about 1/6 radians, // nodding period =2pi/6= pi/3 units, about 3.14 seconds Matrix matRY= Matrix.RotationY(t); // must be turn around too Matrix matDolphin = matS*matRZ*matRY*matT; device.Transform.World=matDolphin; }
15
15 Draw Animated Dolphin private void Render() {....... float alpha = (float)Environment.TickCount/500.0f; // 0.5 second one unit SetDolphin((float)Math.Sin(alpha)); // create dynamic vertices of dolphin mesh // which is seconds one circle animation SetSwimmingPath(); DolphinMesh.DrawSubset(0); }
16
16 Output
17
17 Shadow of Mesh object Under lights, the shadow of a mesh object on another mesh or plane will not be automatically generated unless we write code to make the shadow No shadow on the plane
18
18 Shadow of teapot on plane z = -0. 7 Assume the light is up the teapot and the plane is y= -0. 7. How to make the shadow of teapot on this plane? The method is simple, pick any point P on teapot, then then throw the direction of light, find shadow point Q of P
19
19 Solve point P Q Y = 0.7
20
20 Make shadow vertex array Actually we copy all vertices from teapot mesh, then change every vertex to its shadow points. Here we simply use DrawIndexedUserPrimitives() method. Note: We must remember the rotation Matrix
21
21 Declare ShadowVertex struct ShadowVertex { public Vector3 Position; public Vector3 Normal; } ShadowVertex [] vPot; ShadowVertex [] vShadow; int totalFaces; int totalVerts=0; short[] indices; vPot is used to copy all vertex data from Mesh object. vShadow is used to create shadow for every frame. We first copy data from vPot to vShadow, then change its position values. indices is the index array for drawing.
22
22 Get all vertices & Indices Private bool InitMesh() { Mesh meshTeapot = Mesh.Teapot(device); if(mesh==null) return false; VertexBuffer VB = meshTeapot.VertexBuffer; totalVerts = meshTeapot.NumberVertices ; vPot = new ShadowVertex[total]; vPot = (ShadowVertex[]) VB.Lock(0, typeof(ShadowVertex), LockFlags.None, total); VB.Unlock(); totalFaces = meshTeapot.NumberFaces ; IndexBuffer IB = meshTeapot.IndexBuffer; indices = new short [3*totalFaces] ; indices=(short[])IB.Lock( 0, typeof(short), LockFlags.None, this.totalFaces*3); IB.Unlock(); return true;. }
23
23 SetShadow private void SetShadow() { vShadow = new ShadowVertex[total]; for(int i=0; i<total; i++)vShadow[i] = vPot[i]; // make vertices copy Vector3 v = new Vector3(x, y, 0.2f); // light direction for(int k=0; k<total; k++) { vShadow[k].Normal = new Vector3(0.0f, 1.0f, 0.0f); Vector4 v4= Vector3.Transform (vPot[k].Position, mat); // mat is a rotation matrix, 4 is new position vShadow[k].Position = new Vector3 ( v4.X - x*(v4.Y+0.7f)/y, -0.7f, v4.Z- 0.2f*(v4.Y+0.7f)/y ); // use (V4 +t*v).Y = 0.7 to solve t
24
24 if( vShadow[k].Position.X >2.1f) vShadow[k].Position.X=2.1f; if( vShadow[k].Position.X <-2.1f) vShadow[k].Position.X=-2.1f; if( vShadow[k].Position.Z >1.1f) vShadow[k].Position.Z=1.1f; if( vShadow[k].Position.Z <-1.1f) vShadow[k].Position.Z=-1.1f; } shadow drawing code is : Material mtrl2 = new Material(); mtrl.Ambient = mtrl.Diffuse = Color.Black; device.Material = mtrl2; SetShadow(); device.DrawIndexedUserPrimitives( PrimitiveType.TriangleList, 0, totalVerts, totalFaces, indices, true, vShadow );
25
25 Out put
26
26 ProgressiveMesh ProgressiveMesh is inherited from basic Mesh that can change its resolution. When a Mesh object is far away from view point, to lower its resolution will not decline its graphical quality. ProgressiveMesh can be created from regular mesh. However, we must call Mesh.Clean method first, which will add another vertex where two fans of triangles share the same vertex. public static Mesh Clean( CleanType cleanType, // use Simplification Mesh mesh, GraphicsStream adjacency1, GraphicsStream adjacency2, );
27
27 Create ProgressiveMesh ProgressiveMesh( Mesh cleanedMesh; GraphicsStream adj, // whatever make one AttributeWeight weight, //usenull int minVerts, // use 1 MeshFlags flag//use SimplifyFace ); Note: For the above adj, we just make one even it is null
28
28 Progressive pMesh; // class variables int numF, numMax; private void InitMesh() { ExtendedMaterial[] materials = null; GraphicsStream adj = null; mesh = Mesh.FromFile("wolf.x", MeshFlags.Managed, device, out adj, out materials); meshMaterial = materials[0].Material3D; meshMaterial.Ambient = meshMaterial.Diffuse; meshTexture = TextureLoader.FromFile(device, "wolf.jpg"); Mesh tempMesh = Mesh.Clean(CleanType.Simplification, mesh, adj, adj); pMesh = new ProgressiveMesh(tempMesh, adj, null, 1, MeshFlags.SimplifyFace); pMesh.NumberFaces = tempMesh.NumberFaces ; pMesh.NumberVertices = tempMesh.NumberVertices ; numF = tempMesh.NumberFaces ; numMax = tempMesh.NumberFaces ; }
29
29 bool wire = false;// class variables protected override void OnKeyDown(KeyEventArgs e) { if(e.KeyCode ==Keys.Up) numF +=100; if(e.KeyCode==Keys.Down ) numF -=100; if(numF<0) numF=100; if(numF>numMax) numF=numMax; pMesh.NumberFaces =numF; // change resolution if(e.KeyCode==Keys.W) wire=!wire; } private void Render() {......... if(wire)device.RenderState.FillMode = FillMode.WireFrame; else device.RenderState.FillMode = FillMode.Solid ; device.SetTexture(0, meshTexture); pMesh.DrawSubset(0); // use ProgressiveMesh }
30
30 Output
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.