public void RenderSoftBody(SoftBody softBody) { AlignedFaceArray faces = softBody.Faces; int faceCount = faces.Count; if (faceCount > 0) { PositionedNormal[] vectors = new PositionedNormal[faceCount * 6]; int v = 0; int i; for (i = 0; i < faces.Count; i++) { NodePtrArray nodes = faces[i].N; Node n0 = nodes[0]; Node n1 = nodes[1]; Node n2 = nodes[2]; n0.GetX(out vectors[v].Position); n0.GetNormal(out vectors[v].Normal); n1.GetX(out vectors[v + 1].Position); n1.GetNormal(out vectors[v + 1].Normal); n2.GetX(out vectors[v + 2].Position); n2.GetNormal(out vectors[v + 2].Normal); v += 3; } device.VertexFormat = PositionedNormal.FVF; device.DrawUserPrimitives(PrimitiveType.TriangleList, faces.Count, vectors); } else { AlignedTetraArray tetras = softBody.Tetras; int tetraCount = tetras.Count; if (tetraCount > 0) { PositionedNormal[] vectors = new PositionedNormal[tetraCount * 12]; int v = 0; for (int i = 0; i < tetraCount; i++) { NodePtrArray nodes = tetras[i].Nodes; Vector3 v0 = nodes[0].X; Vector3 v1 = nodes[1].X; Vector3 v2 = nodes[2].X; Vector3 v3 = nodes[3].X; Vector3 v10 = v1 - v0; Vector3 v02 = v0 - v2; Vector3 normal = Vector3.Cross(v10, v02); normal.Normalize(); vectors[v].Position = v0; vectors[v].Normal = normal; vectors[v + 1].Position = v1; vectors[v + 1].Normal = normal; vectors[v + 2].Position = v2; vectors[v + 2].Normal = normal; normal = Vector3.Cross(v10, v3 - v0); normal.Normalize(); vectors[v + 3].Position = v0; vectors[v + 3].Normal = normal; vectors[v + 4].Position = v1; vectors[v + 4].Normal = normal; vectors[v + 5].Position = v3; vectors[v + 5].Normal = normal; normal = Vector3.Cross(v2 - v1, v3 - v1); normal.Normalize(); vectors[v + 6].Position = v1; vectors[v + 6].Normal = normal; vectors[v + 7].Position = v2; vectors[v + 7].Normal = normal; vectors[v + 8].Position = v3; vectors[v + 8].Normal = normal; normal = Vector3.Cross(v02, v3 - v2); normal.Normalize(); vectors[v + 9].Position = v2; vectors[v + 9].Normal = normal; vectors[v + 10].Position = v0; vectors[v + 10].Normal = normal; vectors[v + 11].Position = v3; vectors[v + 11].Normal = normal; v += 12; } device.VertexFormat = PositionedNormal.FVF; device.DrawUserPrimitives(PrimitiveType.TriangleList, tetraCount * 4, vectors); } else if (softBody.Links.Count > 0) { AlignedLinkArray links = softBody.Links; int linkCount = links.Count; int linkColor = System.Drawing.Color.Black.ToArgb(); device.VertexFormat = PositionColored.FVF; PositionColored[] linkArray = new PositionColored[linkCount * 2]; for (int i = 0; i < linkCount; i++) { Link link = links[i]; linkArray[i * 2].Position = link.Nodes[0].X; linkArray[i * 2].Color = linkColor; linkArray[i * 2 + 1].Position = link.Nodes[1].X; linkArray[i * 2 + 1].Color = linkColor; } device.DrawUserPrimitives(PrimitiveType.LineList, links.Count, linkArray); } } }
public void UpdateResource(IPluginOut ForPin, Device OnDevice) { List <Mesh> soft = new List <Mesh>(); if (this.FMesh != null) { this.FMesh.Dispose(); this.FMesh = null; } if (this.FBodies.SliceCount > 0) { int cnt = this.FBodies.SliceCount; for (int i = 0; i < cnt; i++) { SoftBody body = this.FBodies[i]; SoftBodyCustomData sc = (SoftBodyCustomData)body.UserObject; AlignedFaceArray faces = body.Faces; if (FValid[i]) { if (body.Faces.Count > 0) { #region Build from Faces VertexFormat decl; if (sc.HasUV) { decl = VertexFormat.Position | VertexFormat.Normal | VertexFormat.Texture1; } else { decl = VertexFormat.Position | VertexFormat.Normal; } Mesh mesh = new Mesh(OnDevice, faces.Count, faces.Count * 3, MeshFlags.SystemMemory | MeshFlags.Use32Bit, decl); SlimDX.DataStream verts = mesh.LockVertexBuffer(LockFlags.None); SlimDX.DataStream indices = mesh.LockIndexBuffer(LockFlags.None); int j; int uvcnt = 0; for (j = 0; j < faces.Count; j++) { NodePtrArray nodes = faces[j].N; verts.Write(nodes[0].X); verts.Write(nodes[0].Normal); //verts.Position += 12; if (sc.HasUV) { verts.Write(sc.UV[uvcnt]); uvcnt++; verts.Write(sc.UV[uvcnt]); uvcnt++; } verts.Write(nodes[1].X); verts.Write(nodes[1].Normal); //verts.Position += 12; if (sc.HasUV) { verts.Write(sc.UV[uvcnt]); uvcnt++; verts.Write(sc.UV[uvcnt]); uvcnt++; } verts.Write(nodes[2].X); verts.Write(nodes[2].Normal); //verts.Position += 12; if (sc.HasUV) { verts.Write(sc.UV[uvcnt]); uvcnt++; verts.Write(sc.UV[uvcnt]); uvcnt++; } indices.Write(j * 3); indices.Write(j * 3 + 1); indices.Write(j * 3 + 2); } mesh.UnlockVertexBuffer(); mesh.UnlockIndexBuffer(); //mesh.ComputeNormals(); soft.Add(mesh); #endregion } else { #region Build from tetras int tetraCount = body.Tetras.Count; int vertexCount = tetraCount * 12; VertexFormat decl; if (sc.HasUV) { decl = VertexFormat.Position | VertexFormat.Normal | VertexFormat.Texture1; } else { decl = VertexFormat.Position | VertexFormat.Normal; } Mesh mesh = new Mesh(OnDevice, tetraCount * 4, vertexCount, MeshFlags.SystemMemory | MeshFlags.Use32Bit, decl); SlimDX.DataStream indices = mesh.LockIndexBuffer(LockFlags.Discard); for (int idx = 0; idx < vertexCount; idx++) { indices.Write(idx); } mesh.UnlockIndexBuffer(); SlimDX.DataStream verts = mesh.LockVertexBuffer(LockFlags.None); foreach (Tetra t in body.Tetras) { NodePtrArray nodes = t.Nodes; verts.Write(nodes[2].X); verts.Write(nodes[2].Normal); //verts.Position += 12; verts.Write(nodes[1].X); verts.Write(nodes[1].Normal); //verts.Position += 12; verts.Write(nodes[0].X); verts.Write(nodes[0].Normal); //verts.Position += 12; verts.Write(nodes[0].X); verts.Write(nodes[0].Normal); //verts.Position += 12; verts.Write(nodes[1].X); verts.Write(nodes[1].Normal); //verts.Position += 12; verts.Write(nodes[3].X); verts.Write(nodes[3].Normal); //verts.Position += 12; verts.Write(nodes[2].X); verts.Write(nodes[2].Normal); //verts.Position += 12; verts.Write(nodes[3].X); verts.Write(nodes[3].Normal); //verts.Position += 12; verts.Write(nodes[1].X); verts.Write(nodes[1].Normal); //verts.Position += 12; verts.Write(nodes[2].X); verts.Write(nodes[2].Normal); //verts.Position += 12; verts.Write(nodes[0].X); verts.Write(nodes[0].Normal); //verts.Position += 12; verts.Write(nodes[3].X); verts.Write(nodes[3].Normal); //verts.Position += 12; } mesh.UnlockVertexBuffer(); mesh.UnlockIndexBuffer(); //mesh.ComputeNormals(); soft.Add(mesh); #endregion } } } Mesh merge = null; if (OnDevice is DeviceEx) { merge = Mesh.Concatenate(OnDevice, soft.ToArray(), MeshFlags.Use32Bit); } else { merge = Mesh.Concatenate(OnDevice, soft.ToArray(), MeshFlags.Use32Bit | MeshFlags.Managed); } this.FMesh = merge; foreach (Mesh m in soft) { m.Dispose(); } } }
public void RenderSoftBody(SoftBody softBody) { Cull cullMode = device.GetRenderState <Cull>(RenderState.CullMode); device.SetRenderState(RenderState.CullMode, Cull.None); AlignedFaceArray faces = softBody.Faces; int faceCount = faces.Count; if (faceCount > 0) { PositionedNormal[] vectors = new PositionedNormal[faceCount * 3]; int v = 0; for (int i = 0; i < faceCount; i++) { NodePtrArray nodes = faces[i].Nodes; Node n0 = nodes[0]; Node n1 = nodes[1]; Node n2 = nodes[2]; vectors[v].Position = n0.Position; vectors[v].Normal = n0.Normal; vectors[v + 1].Position = n1.Position; vectors[v + 1].Normal = n1.Normal; vectors[v + 2].Position = n2.Position; vectors[v + 2].Normal = n2.Normal; v += 3; } device.VertexFormat = VertexFormat.PositionNormal; device.DrawUserPrimitives(PrimitiveType.TriangleList, faces.Count, vectors); } else { AlignedTetraArray tetras = softBody.Tetras; int tetraCount = tetras.Count; if (tetraCount > 0) { PositionedNormal[] vectors = new PositionedNormal[tetraCount * 12]; int v = 0; for (int i = 0; i < tetraCount; i++) { NodePtrArray nodes = tetras[i].Nodes; BulletSharp.Math.Vector3 v0 = nodes[0].Position; BulletSharp.Math.Vector3 v1 = nodes[1].Position; BulletSharp.Math.Vector3 v2 = nodes[2].Position; BulletSharp.Math.Vector3 v3 = nodes[3].Position; BulletSharp.Math.Vector3 v10 = v1 - v0; BulletSharp.Math.Vector3 v02 = v0 - v2; BulletSharp.Math.Vector3 normal = BulletSharp.Math.Vector3.Cross(v10, v02); normal.Normalize(); vectors[v].Position = v0; vectors[v].Normal = normal; vectors[v + 1].Position = v1; vectors[v + 1].Normal = normal; vectors[v + 2].Position = v2; vectors[v + 2].Normal = normal; normal = BulletSharp.Math.Vector3.Cross(v10, v3 - v0); normal.Normalize(); vectors[v + 3].Position = v0; vectors[v + 3].Normal = normal; vectors[v + 4].Position = v1; vectors[v + 4].Normal = normal; vectors[v + 5].Position = v3; vectors[v + 5].Normal = normal; normal = BulletSharp.Math.Vector3.Cross(v2 - v1, v3 - v1); normal.Normalize(); vectors[v + 6].Position = v1; vectors[v + 6].Normal = normal; vectors[v + 7].Position = v2; vectors[v + 7].Normal = normal; vectors[v + 8].Position = v3; vectors[v + 8].Normal = normal; normal = BulletSharp.Math.Vector3.Cross(v02, v3 - v2); normal.Normalize(); vectors[v + 9].Position = v2; vectors[v + 9].Normal = normal; vectors[v + 10].Position = v0; vectors[v + 10].Normal = normal; vectors[v + 11].Position = v3; vectors[v + 11].Normal = normal; v += 12; } device.VertexFormat = VertexFormat.PositionNormal; device.DrawUserPrimitives(PrimitiveType.TriangleList, tetraCount * 4, vectors); } else if (softBody.Links.Count > 0) { AlignedLinkArray links = softBody.Links; int linkCount = links.Count; int linkColor = System.Drawing.Color.Black.ToArgb(); device.VertexFormat = VertexFormat.Position | VertexFormat.Diffuse; PositionColored[] linkArray = new PositionColored[linkCount * 2]; for (int i = 0; i < linkCount; i++) { Link link = links[i]; linkArray[i * 2].Position = link.Nodes[0].Position; linkArray[i * 2].Color = linkColor; linkArray[i * 2 + 1].Position = link.Nodes[1].Position; linkArray[i * 2 + 1].Color = linkColor; } device.DrawUserPrimitives(PrimitiveType.LineList, links.Count, linkArray); } } device.SetRenderState(RenderState.CullMode, cullMode); }
public void Update(IPluginIO pin, DX11RenderContext context) { for (int i = 0; i < this.FOutput.SliceCount; i++) { if (this.FOutput[i].Contains(context)) { this.FOutput[i].Dispose(context); } } if (this.FBodies.SliceCount > 0) { int cnt = this.FBodies.SliceCount; for (int i = 0; i < cnt; i++) { SoftBody body = this.FBodies[i]; SoftBodyCustomData sc = (SoftBodyCustomData)body.UserObject; AlignedFaceArray faces = body.Faces; if (FValid[i]) { if (body.Faces.Count > 0) { #region Build from Faces DX11IndexedGeometry geom = new DX11IndexedGeometry(context); geom.VerticesCount = faces.Count * 3; if (sc.HasUV) { geom.InputLayout = Pos3Norm3Tex2Vertex.Layout; geom.VertexSize = Pos3Norm3Tex2Vertex.VertexSize; } else { geom.InputLayout = Pos3Norm3Vertex.Layout; geom.VertexSize = Pos3Norm3Vertex.VertexSize; } //Mesh mesh = new Mesh(OnDevice, faces.Count, faces.Count * 3, MeshFlags.SystemMemory | MeshFlags.Use32Bit, decl); SlimDX.DataStream verts = new SlimDX.DataStream(geom.VerticesCount * geom.VertexSize * 3, false, true); SlimDX.DataStream indices = new SlimDX.DataStream(faces.Count * sizeof(int) * 3, false, true); int j; int uvcnt = 0; for (j = 0; j < faces.Count; j++) { NodePtrArray nodes = faces[j].N; verts.Write(nodes[0].X); verts.Write(nodes[0].Normal); //verts.Position += 12; if (sc.HasUV) { verts.Write(sc.UV[uvcnt]); uvcnt++; verts.Write(sc.UV[uvcnt]); uvcnt++; } verts.Write(nodes[1].X); verts.Write(nodes[1].Normal); //verts.Position += 12; if (sc.HasUV) { verts.Write(sc.UV[uvcnt]); uvcnt++; verts.Write(sc.UV[uvcnt]); uvcnt++; } verts.Write(nodes[2].X); verts.Write(nodes[2].Normal); //verts.Position += 12; if (sc.HasUV) { verts.Write(sc.UV[uvcnt]); uvcnt++; verts.Write(sc.UV[uvcnt]); uvcnt++; } indices.Write(j * 3); indices.Write(j * 3 + 1); indices.Write(j * 3 + 2); } geom.VertexBuffer = BufferHelper.CreateVertexBuffer(context, verts, false, true); geom.HasBoundingBox = false; DX11IndexBuffer ibo = new DX11IndexBuffer(context, indices, false, true); geom.IndexBuffer = ibo; this.FOutput[i][context] = geom; #endregion } } } } }
public void UpdateSoftBody(SoftBody softBody, ShapeData shapeData) { AlignedFaceArray faces = softBody.Faces; if (faces.Count != 0) { shapeData.VertexCount = faces.Count * 3; Vector3[] vectors = new Vector3[shapeData.VertexCount * 2]; int v = 0; int i; for (i = 0; i < faces.Count; i++) { NodePtrArray nodes = faces[i].N; Node n0 = nodes[0]; Node n1 = nodes[1]; Node n2 = nodes[2]; n0.GetX(out vectors[v]); n0.GetNormal(out vectors[v + 1]); n1.GetX(out vectors[v + 2]); n1.GetNormal(out vectors[v + 3]); n2.GetX(out vectors[v + 4]); n2.GetNormal(out vectors[v + 5]); v += 6; } shapeData.SetDynamicVertexBuffer(device, vectors); } else { AlignedTetraArray tetras = softBody.Tetras; int tetraCount = tetras.Count; if (tetraCount != 0) { shapeData.VertexCount = tetraCount * 12; Vector3[] vectors = new Vector3[tetraCount * 24]; int v = 0; for (int i = 0; i < tetraCount; i++) { NodePtrArray nodes = tetras[i].Nodes; Vector3 v0 = nodes[0].X; Vector3 v1 = nodes[1].X; Vector3 v2 = nodes[2].X; Vector3 v3 = nodes[3].X; Vector3 v10 = v1 - v0; Vector3 v02 = v0 - v2; Vector3 normal = Vector3.Cross(v10, v02); vectors[v] = v0; vectors[v + 1] = normal; vectors[v + 2] = v1; vectors[v + 3] = normal; vectors[v + 4] = v2; vectors[v + 5] = normal; normal = Vector3.Cross(v10, v3 - v0); vectors[v + 6] = v0; vectors[v + 7] = normal; vectors[v + 8] = v1; vectors[v + 9] = normal; vectors[v + 10] = v3; vectors[v + 11] = normal; normal = Vector3.Cross(v2 - v1, v3 - v1); vectors[v + 12] = v1; vectors[v + 13] = normal; vectors[v + 14] = v2; vectors[v + 15] = normal; vectors[v + 16] = v3; vectors[v + 17] = normal; normal = Vector3.Cross(v02, v3 - v2); vectors[v + 18] = v2; vectors[v + 19] = normal; vectors[v + 20] = v0; vectors[v + 21] = normal; vectors[v + 22] = v3; vectors[v + 23] = normal; v += 24; } shapeData.SetDynamicVertexBuffer(device, vectors); } else if (softBody.Links.Count != 0) { AlignedLinkArray links = softBody.Links; int linkCount = links.Count; shapeData.VertexCount = linkCount * 2; Vector3[] vectors = new Vector3[linkCount * 4]; for (int i = 0; i < linkCount; i++) { NodePtrArray nodes = links[i].Nodes; nodes[0].GetX(out vectors[i * 4]); nodes[1].GetX(out vectors[i * 4 + 2]); } shapeData.PrimitiveTopology = PrimitiveTopology.LineList; shapeData.SetDynamicVertexBuffer(device, vectors); } else { throw new NotImplementedException(); } } }