public void Init( DecalCreator creator, Vertex[] vertices, int[] indices, string materialName, MapObject parentMapObject) { this.creator = creator; this.vertices = vertices; this.indices = indices; this.sourceMaterialName = materialName; this.parentMapObject = parentMapObject; if( parentMapObject != null ) AddRelationship( parentMapObject ); CreateDecal(); }
void CreateMesh() { Vec3 size = new Vec3( .97f, .97f, .1f ); Vec3[] positions; Vec3[] normals; int[] indices; GeometryGenerator.GenerateBox( size, out positions, out normals, out indices ); string meshName = MeshManager.Instance.GetUniqueName( string.Format( "JigsawPuzzlePiece[{0},{1}]", index.X, index.Y ) ); mesh = MeshManager.Instance.CreateManual( meshName ); //create submesh SubMesh subMesh = mesh.CreateSubMesh(); subMesh.UseSharedVertices = false; //init VertexData VertexDeclaration declaration = subMesh.VertexData.VertexDeclaration; declaration.AddElement( 0, 0, VertexElementType.Float3, VertexElementSemantic.Position ); declaration.AddElement( 0, 12, VertexElementType.Float3, VertexElementSemantic.Normal ); declaration.AddElement( 0, 24, VertexElementType.Float2, VertexElementSemantic.TextureCoordinates, 0 ); VertexBufferBinding bufferBinding = subMesh.VertexData.VertexBufferBinding; HardwareVertexBuffer vertexBuffer = HardwareBufferManager.Instance.CreateVertexBuffer( 32, positions.Length, HardwareBuffer.Usage.StaticWriteOnly ); bufferBinding.SetBinding( 0, vertexBuffer, true ); subMesh.VertexData.VertexCount = positions.Length; unsafe { Vertex* buffer = (Vertex*)vertexBuffer.Lock( HardwareBuffer.LockOptions.Normal ); for( int n = 0; n < positions.Length; n++ ) { Vertex vertex = new Vertex(); vertex.position = positions[ n ]; vertex.normal = normals[ n ]; if( JigsawPuzzleManager.Instance != null ) { Vec2I pieceCount = JigsawPuzzleManager.Instance.PieceCount; Vec2I i = index; if( vertex.position.X > 0 ) i.X++; if( vertex.position.Y > 0 ) i.Y++; vertex.texCoord = new Vec2( (float)i.X / (float)pieceCount.X, 1.0f - (float)i.Y / (float)pieceCount.Y ); } *buffer = vertex; buffer++; } vertexBuffer.Unlock(); } //calculate mesh bounds Bounds bounds = Bounds.Cleared; float radius = 0; foreach( Vec3 position in positions ) { bounds.Add( position ); float r = position.Length(); if( r > radius ) radius = r; } mesh.SetBoundsAndRadius( bounds, radius ); //init IndexData subMesh.IndexData = IndexData.CreateFromArray( indices, 0, indices.Length, false ); //init material subMesh.MaterialName = "JigsawPuzzleImage"; }
void UpdateMeshVertices() { SubMesh subMesh = mesh.SubMeshes[ 0 ]; Vec2 cellSize = 1.0f / Type.GridSize.ToVec2(); HardwareVertexBuffer vertexBuffer = subMesh.VertexData.VertexBufferBinding.GetBuffer( 0 ); unsafe { Vertex* buffer = (Vertex*)vertexBuffer.Lock( HardwareBuffer.LockOptions.Normal ).ToPointer(); subMesh.VertexData.VertexCount = ( Type.GridSize.X + 1 ) * ( Type.GridSize.Y + 1 ); for( int y = 0; y < Type.GridSize.Y + 1; y++ ) { for( int x = 0; x < Type.GridSize.X + 1; x++ ) { Vertex vertex = new Vertex(); vertex.position = new Vec3( 0, (float)( x - Type.GridSize.X / 2 ) * cellSize.X, (float)( y - Type.GridSize.Y / 2 ) * cellSize.Y ); vertex.normal = new Vec3( 1, 0, 0 ); vertex.texCoord = new Vec2( (float)x / (float)Type.GridSize.X, 1.0f - (float)y / (float)Type.GridSize.Y ); *buffer = vertex; buffer++; } } vertexBuffer.Unlock(); } }
private unsafe void UpdateGeometry() { DestroyGeometry(); Curve positionCurve = GetPositionCurve(); Curve radiusCurve = null; { bool existsSpecialRadius = false; foreach (MapCurvePoint point in Points) { RenderableCurvePoint point2 = point as RenderableCurvePoint; if (point2 != null && point2.OverrideRadius >= 0) { existsSpecialRadius = true; break; } } if (existsSpecialRadius) { switch (radiusCurveType) { case RadiusCurveTypes.UniformCubicSpline: radiusCurve = new UniformCubicSpline(); break; case RadiusCurveTypes.Bezier: radiusCurve = new BezierCurve(); break; case RadiusCurveTypes.Line: radiusCurve = new LineCurve(); break; } for (int n = 0; n < Points.Count; n++) { MapCurvePoint point = Points[n]; if (!point.Editor_IsExcludedFromWorld()) { float rad = radius; RenderableCurvePoint renderableCurvePoint = point as RenderableCurvePoint; if (renderableCurvePoint != null && renderableCurvePoint.OverrideRadius >= 0) rad = renderableCurvePoint.OverrideRadius; radiusCurve.AddValue(point.Time, new Vec3(rad, 0, 0)); } } } } //create mesh Vertex[] vertices = null; int[] indices = null; if (positionCurve != null && positionCurve.Values.Count > 1 && Points.Count >= 2) { Vec3 positionOffset = -Position; int steps = (Points.Count - 1) * pathSteps + 1; int vertexCount = steps * (shapeSegments + 1); int indexCount = (steps - 1) * shapeSegments * 2 * 3; vertices = new Vertex[vertexCount]; indices = new int[indexCount]; //fill data { int currentVertex = 0; int currentIndex = 0; float currentDistance = 0; Vec3 lastPosition = Vec3.Zero; Quat lastRot = Quat.Identity; for (int nStep = 0; nStep < steps; nStep++) { int startStepVertexIndex = currentVertex; float coefficient = (float)nStep / (float)(steps - 1); Vec3 pos = CalculateCurvePointByCoefficient(coefficient) + positionOffset; Quat rot; { Vec3 v = CalculateCurvePointByCoefficient(coefficient + .3f / (float)(steps - 1)) - CalculateCurvePointByCoefficient(coefficient); if (v != Vec3.Zero) rot = Quat.FromDirectionZAxisUp(v.GetNormalize()); else rot = lastRot; } if (nStep != 0) currentDistance += (pos - lastPosition).Length(); float rad; if (radiusCurve != null) { Range range = new Range(radiusCurve.Times[0], radiusCurve.Times[radiusCurve.Times.Count - 1]); float t = range.Minimum + (range.Maximum - range.Minimum) * coefficient; rad = radiusCurve.CalculateValueByTime(t).X; } else rad = radius; for (int nSegment = 0; nSegment < shapeSegments + 1; nSegment++) { float rotateCoefficient = ((float)nSegment / (float)(shapeSegments)); float angle = rotateCoefficient * MathFunctions.PI * 2; Vec3 p = pos + rot * new Vec3(0, MathFunctions.Cos(angle) * rad, MathFunctions.Sin(angle) * rad); Vertex vertex = new Vertex(); vertex.position = p; Vec3 pp = p - pos; if (pp != Vec3.Zero) vertex.normal = pp.GetNormalize(); else vertex.normal = Vec3.XAxis; //vertex.normal = ( p - pos ).GetNormalize(); vertex.texCoord = new Vec2(currentDistance * textureCoordinatesTilesPerMeter, rotateCoefficient + .25f); vertex.tangent = new Vec4(rot.GetForward(), 1); vertices[currentVertex++] = vertex; } if (nStep < steps - 1) { for (int nSegment = 0; nSegment < shapeSegments; nSegment++) { indices[currentIndex++] = startStepVertexIndex + nSegment; indices[currentIndex++] = startStepVertexIndex + nSegment + 1; indices[currentIndex++] = startStepVertexIndex + nSegment + 1 + shapeSegments + 1; indices[currentIndex++] = startStepVertexIndex + nSegment + 1 + shapeSegments + 1; indices[currentIndex++] = startStepVertexIndex + nSegment + shapeSegments + 1; indices[currentIndex++] = startStepVertexIndex + nSegment; } } lastPosition = pos; lastRot = rot; } if (currentVertex != vertexCount) Log.Fatal("RenderableCurve: UpdateRenderingGeometry: currentVertex != vertexCount."); if (currentIndex != indexCount) Log.Fatal("RenderableCurve: UpdateRenderingGeometry: currentIndex != indexCount."); } if (vertices.Length != 0 && indices.Length != 0) { //create mesh string meshName = MeshManager.Instance.GetUniqueName( string.Format("__RenderableCurve_{0}_{1}", Name, uniqueMeshIdentifier)); uniqueMeshIdentifier++; //string meshName = MeshManager.Instance.GetUniqueName( string.Format( "__RenderableCurve_{0}", Name ) ); mesh = MeshManager.Instance.CreateManual(meshName); SubMesh subMesh = mesh.CreateSubMesh(); subMesh.UseSharedVertices = false; //init vertexData VertexDeclaration declaration = subMesh.VertexData.VertexDeclaration; declaration.AddElement(0, 0, VertexElementType.Float3, VertexElementSemantic.Position); declaration.AddElement(0, 12, VertexElementType.Float3, VertexElementSemantic.Normal); declaration.AddElement(0, 24, VertexElementType.Float2, VertexElementSemantic.TextureCoordinates, 0); declaration.AddElement(0, 32, VertexElementType.Float4, VertexElementSemantic.Tangent, 0); fixed (Vertex* pVertices = vertices) { subMesh.VertexData = VertexData.CreateFromArray(declaration, (IntPtr)pVertices, vertices.Length * Marshal.SizeOf(typeof(Vertex))); } subMesh.IndexData = IndexData.CreateFromArray(indices, 0, indices.Length, false); //set material subMesh.MaterialName = materialName; //set mesh gabarites Bounds bounds = Bounds.Cleared; foreach (Vertex vertex in vertices) bounds.Add(vertex.position); mesh.SetBoundsAndRadius(bounds, bounds.GetRadius()); } } //create MeshObject, SceneNode if (mesh != null) { meshObject = SceneManager.Instance.CreateMeshObject(mesh.Name); if (meshObject != null) { meshObject.SetMaterialNameForAllSubObjects(materialName); meshObject.CastShadows = true; sceneNode = new SceneNode(); sceneNode.Attach(meshObject); //apply offset sceneNode.Position = Position; MapObject.AssociateSceneNodeWithMapObject(sceneNode, this); } } //create collision body if (mesh != null && collision) { Vec3[] positions = new Vec3[vertices.Length]; for (int n = 0; n < vertices.Length; n++) positions[n] = vertices[n].position; string meshPhysicsMeshName = PhysicsWorld.Instance.AddCustomMeshGeometry(positions, indices, null, MeshShape.MeshTypes.TriangleMesh, 0, 0); collisionBody = PhysicsWorld.Instance.CreateBody(); collisionBody.Static = true; collisionBody._InternalUserData = this; collisionBody.Position = Position; MeshShape shape = collisionBody.CreateMeshShape(); shape.MeshName = meshPhysicsMeshName; shape.MaterialName = CollisionMaterialName; shape.ContactGroup = (int)ContactGroup.Collision; //shape.VehicleDrivableSurface = collisionVehicleDrivableSurface; collisionBody.PushedToWorld = true; } needUpdate = false; }
unsafe void MakeRoad() { if (end_make == false && HeightmapTerrain.Instances[0] != null) { Vertex[] vertices = new Vertex[vertex_count]; ushort[] indices = new ushort[index_count]; for (int i = 0; i < index_count; i++) { indices[i] = (ushort)(vertex_ind[i]); } for (int i = 0; i < vertex_count; i++) { Vertex vertex = new Vertex(); Vec3 p = ((vertex_pos[i] * attached_mesh.ScaleOffset) * Rotation) + (Position + attached_mesh.PositionOffset); Vec2 mesh_vertex_pos = new Vec2(p.X, p.Y); float terrain_height = HeightmapTerrain.Instances[0].Position.Z + HeightmapTerrain.Instances[0].GetHeight(mesh_vertex_pos, false); Vec3 terrain_norm = HeightmapTerrain.Instances[0].GetNormal(mesh_vertex_pos); vertex.position = new Vec3(vertex_pos[i].X, vertex_pos[i].Y, terrain_height); vertex.normal = terrain_norm; vertex.texCoord = vertex_tc[i]; vertices[i] = vertex; } SubMesh sub_mesh = mesh.SubMeshes[0]; { HardwareVertexBuffer vertex_buffer = sub_mesh.VertexData.VertexBufferBinding.GetBuffer(0); IntPtr buffer = vertex_buffer.Lock(HardwareBuffer.LockOptions.Discard); fixed (Vertex* pvertices = vertices) { NativeUtils.CopyMemory(buffer, (IntPtr)pvertices, vertices.Length * sizeof(Vertex)); } vertex_buffer.Unlock(); } { HardwareIndexBuffer index_buffer = sub_mesh.IndexData.IndexBuffer; IntPtr buffer = index_buffer.Lock(HardwareBuffer.LockOptions.Discard); fixed (ushort* pindices = indices) { NativeUtils.CopyMemory(buffer, (IntPtr)pindices, indices.Length * sizeof(ushort)); } index_buffer.Unlock(); } if (EngineApp.Instance.ApplicationType == EngineApp.ApplicationTypes.Simulation) { end_make = true; first_init_mesh = true; } } }
private unsafe void UpdateGeometry(float time) { //generate geometry Vertex[] vertices = new Vertex[tesselation * tesselation]; ushort[] indices = new ushort[(tesselation - 1) * (tesselation - 1) * 6]; { //vertices int vertexPosition = 0; for (int y = 0; y < tesselation; y++) { for (int x = 0; x < tesselation; x++) { Vertex vertex = new Vertex(); Vec2 pos2 = new Vec2( (float)x / (float)(tesselation - 1) - .5f, (float)y / (float)(tesselation - 1) - .5f); float posZ = MathFunctions.Sin(pos2.Length() * 30 - time * 2) / 2; MathFunctions.Clamp(ref posZ, -5f, .5f); vertex.position = new Vec3(pos2.X, pos2.Y, posZ) * Scale; vertex.normal = Vec3.Zero; vertex.texCoord = new Vec2(pos2.X + .5f, pos2.Y + .5f); //vertex.tangents = Vec4.Zero; vertices[vertexPosition] = vertex; vertexPosition++; } } //indices int indexPosition = 0; for (int y = 0; y < tesselation - 1; y++) { for (int x = 0; x < tesselation - 1; x++) { indices[indexPosition] = (ushort)(tesselation * y + x); indexPosition++; indices[indexPosition] = (ushort)(tesselation * y + x + 1); indexPosition++; indices[indexPosition] = (ushort)(tesselation * (y + 1) + x + 1); indexPosition++; indices[indexPosition] = (ushort)(tesselation * (y + 1) + x + 1); indexPosition++; indices[indexPosition] = (ushort)(tesselation * (y + 1) + x); indexPosition++; indices[indexPosition] = (ushort)(tesselation * y + x); indexPosition++; } } //calculate vertex normals fixed (Vertex* pVertices = vertices) { int triangleCount = indices.Length / 3; for (int n = 0; n < triangleCount; n++) { int index0 = indices[n * 3 + 0]; int index1 = indices[n * 3 + 1]; int index2 = indices[n * 3 + 2]; Vec3 pos0 = pVertices[index0].position; Vec3 pos1 = pVertices[index1].position; Vec3 pos2 = pVertices[index2].position; Vec3 normal = Vec3.Cross(pos1 - pos0, pos2 - pos0); normal.Normalize(); pVertices[index0].normal += normal; pVertices[index1].normal += normal; pVertices[index2].normal += normal; } //normalize for (int n = 0; n < vertices.Length; n++) pVertices[n].normal = pVertices[n].normal.GetNormalize(); } } SubMesh subMesh = mesh.SubMeshes[0]; //copy data to vertex buffer { HardwareVertexBuffer vertexBuffer = subMesh.VertexData.VertexBufferBinding.GetBuffer(0); IntPtr buffer = vertexBuffer.Lock(HardwareBuffer.LockOptions.Discard); fixed (Vertex* pVertices = vertices) { NativeUtils.CopyMemory(buffer, (IntPtr)pVertices, vertices.Length * sizeof(Vertex)); } vertexBuffer.Unlock(); } //copy data to index buffer { HardwareIndexBuffer indexBuffer = subMesh.IndexData.IndexBuffer; IntPtr buffer = indexBuffer.Lock(HardwareBuffer.LockOptions.Discard); fixed (ushort* pIndices = indices) { NativeUtils.CopyMemory(buffer, (IntPtr)pIndices, indices.Length * sizeof(ushort)); } indexBuffer.Unlock(); } ////calculate mesh tangent vectors //mesh.BuildTangentVectors( VertexElementSemantic.Tangent, 0, 0, true ); }
public void addVertex(Vertex A, int k) { albero[k] = A; //aggiunge un vertice 'A' nella posizione 'k' dell'array 'albero' }