/// <summary> /// Compute position normal mesh /// </summary> /// <param name="surfaceMesh">The position mesh</param> /// <returns>A <see cref="VertexBuffer"/> that represents the surface mesh with normals.</returns> private VertexBuffer ComputePositionNormalMesh(SpatialSurfaceMesh surfaceMesh) { var surfacePositions = surfaceMesh.VertexPositions; var surfaceNormals = surfaceMesh.VertexNormals; VertexBuffer vertexBuffer = new VertexBuffer(VertexPositionNormal.VertexFormat); VertexPositionNormal[] vertices = new VertexPositionNormal[surfacePositions.ElementCount]; using (var positionStream = surfacePositions.Data.AsStream()) using (var normalStream = surfaceNormals.Data.AsStream()) using (var positionReader = new BinaryReader(positionStream)) using (var normalReader = new BinaryReader(normalStream)) { for (int i = 0; i < vertices.Length; i++) { // Read position vertices[i].Position.X = positionReader.ReadSingle(); vertices[i].Position.Y = positionReader.ReadSingle(); vertices[i].Position.Z = positionReader.ReadSingle(); positionReader.ReadSingle(); // Unused 4th float // Read normal vertices[i].Normal.X = normalReader.ReadSingle(); vertices[i].Normal.Y = normalReader.ReadSingle(); vertices[i].Normal.Z = normalReader.ReadSingle(); normalReader.ReadSingle(); // Unused 4th float } } vertexBuffer.SetData(vertices); return(vertexBuffer); }
public static VertexPositionNormal[] GenerateSkyboxCube() { var positions = new[] { -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f }; VertexPositionNormal[] vertices = new VertexPositionNormal[36]; for (int i = 0; i < 108; i += 3) { vertices[i / 3] = new VertexPositionNormal(new Vector3(positions[i], positions[i + 1], positions[i + 2]), Vector3.Zero); } return(vertices); }
public DecorRenderer(RenderBase rb) { RenderBase = rb; paramsBuffer = new UConstantBuffer(RenderBase, Utilities.SizeOf <Vector4>() * 2); var shaderFlags = #if DEBUG ShaderFlags.Debug; #else ShaderFlags.None; #endif vertexShaderSway = new UVertexShader(RenderBase, "shaders/Vertex_PNI_Wave.hlsl", VertexPositionNormal.InputElementsInstanced); using (var pixelShaderByteCode = ShaderBytecode.CompileFromFile("shaders/Pixel_PNI_FishPointLightsAbs.hlsl", "main", "ps_4_0", shaderFlags)) plantPixelShader = new PixelShader(RenderBase.Device, pixelShaderByteCode); vertexShader = new UVertexShader(RenderBase, "shaders/Vertex_PN_Standard.hlsl", VertexPositionNormal.InputElements); using (var pixelShaderByteCode = ShaderBytecode.CompileFromFile("shaders/Pixel_PC_FishPointLightsAbs.hlsl", "main", "ps_4_0", shaderFlags)) pixelShader = new PixelShader(RenderBase.Device, pixelShaderByteCode); plantVertexBuffer = Buffer.Create(RenderBase.Device, BindFlags.VertexBuffer, VertexPositionNormal.LoadSTL("models/plant.stl", out plantVertCount)); floorVertexBuffer = Buffer.Create(RenderBase.Device, BindFlags.VertexBuffer, VertexPositionNormal.LoadSTL("models/tankFloor.stl", out floorVertCount)); /*plantData = new Vector4[] * { * new Vector4(-0.8f, .07f, 0, 0.1f), * new Vector4(0.9f, .04f, 0, 0.2f), * new Vector4(-0.95f, .06f, 0, 0.15f), * }; * plantWaveSpeed = new float[] * { * 1.0f, * 1.2f, * 0.6f, * };*/ Random rnd = new Random(); plantData = new Vector4[500]; plantWaveSpeed = new float[plantData.Length]; for (int i = 0; i < plantData.Length; i++) { var sizeMul = 0.333f; if (rnd.Next(0, 25) == 0) { sizeMul = 0.5f; } plantData[i] = new Vector4(rnd.NextFloat(-16.0f / 9.0f * 1.5f, 16.0f / 9.0f * 1.5f), rnd.NextFloat(0.01f, 0.1f) * sizeMul, 0, rnd.NextFloat(0.05f, 0.3f)); plantWaveSpeed[i] = rnd.NextFloat(0.01f, 2.0f); } plantInstanceBuffer = new DynamicVertexBuffer(rb, (Utilities.SizeOf <Matrix>() + Utilities.SizeOf <Vector4>()) * plantData.Length); }
public static int GetVertexSize(VertexFormatBits format) { switch (format) { case VertexFormatBits.Position: return(VertexPosition.GetSizeInFloats()); case VertexFormatBits.PositionColored: return(VertexPositionColored.GetSizeInFloats()); case VertexFormatBits.PositionNormal: return(VertexPositionNormal.GetSizeInFloats()); case VertexFormatBits.PositionNormalColored: return(VertexPositionNormalColored.GetSizeInFloats()); default: break; } return(VertexPosition.GetSizeInFloats()); }
public static ModelRoot ToGltf(this SimpleSkin skn, Dictionary <string, MagickImage> materialTextues = null) { SceneBuilder sceneBuilder = new SceneBuilder("model"); var meshBuilder = VERTEX.CreateCompatibleMesh(); foreach (SimpleSkinSubmesh submesh in skn.Submeshes) { MaterialBuilder material = new MaterialBuilder(submesh.Name).WithUnlitShader(); var submeshPrimitive = meshBuilder.UsePrimitive(material); // Assign submesh Image if (materialTextues is not null && materialTextues.ContainsKey(submesh.Name)) { MagickImage submeshImage = materialTextues[submesh.Name]; AssignMaterialTexture(material, submeshImage); } // Build vertices var vertices = new List <VERTEX>(submesh.Vertices.Count); foreach (SimpleSkinVertex vertex in submesh.Vertices) { VertexPositionNormal positionNormal = new VertexPositionNormal(vertex.Position, vertex.Normal); VertexTexture1 uv = new VertexTexture1(vertex.UV); vertices.Add(new VERTEX(positionNormal, uv)); } // Add vertices to primitive for (int i = 0; i < submesh.Indices.Count; i += 3) { VERTEX v1 = vertices[submesh.Indices[i + 0]]; VERTEX v2 = vertices[submesh.Indices[i + 1]]; VERTEX v3 = vertices[submesh.Indices[i + 2]]; submeshPrimitive.AddTriangle(v1, v2, v3); } } sceneBuilder.AddRigidMesh(meshBuilder, new AffineTransform(new Vector3(-1, 1, 1), Quaternion.Identity, Vector3.Zero).Matrix); return(sceneBuilder.ToGltf2()); }
public void CreateMeshInSanitizedMode() { var mesh = VERTEX2.CreateCompatibleMesh(); mesh.VertexPreprocessor.SetSanitizerPreprocessors(); var prim = mesh.UsePrimitive(Materials.MaterialBuilder.CreateDefault(), 1); var p = new VertexPositionNormal(Vector3.UnitX, new Vector3(float.NaN)); var m = new VertexColor1Texture1(Vector4.One * 7, new Vector2(float.NaN)); var s = new VertexJoints4((0, 2), (1, 7), (2, 6), (3, 5)); var v1Idx = prim.AddPoint(new VERTEX2(p, m, s)); var v1Bis = prim.Vertices[v1Idx]; NumericsAssert.AreEqual(v1Bis.Geometry.Position, Vector3.UnitX); NumericsAssert.AreEqual(v1Bis.Geometry.Normal, Vector3.UnitX); NumericsAssert.AreEqual(v1Bis.Material.Color, Vector4.One); NumericsAssert.AreEqual(v1Bis.Material.TexCoord, Vector2.Zero); NumericsAssert.AreEqual(v1Bis.Skinning.Joints, new Vector4(1, 2, 3, 0)); NumericsAssert.AreEqual(v1Bis.Skinning.Weights, new Vector4(7, 6, 5, 2) / (7f + 6f + 5f + 2f)); }
/// <summary> /// Create a vertex array with calculated normals. /// </summary> /// <param name="vertices">A vertex array, assumes normal values are zero.</param> /// <param name="indices">An index array for the skydome.</param> public VertexPositionNormal[] CalculateVertexNormals(VertexPositionNormal[] vertices, int[] indices) { for (int i = 0; i < indices.Length / 3; i++) { int index1 = indices[i * 3]; int index2 = indices[i * 3 + 1]; int index3 = indices[i * 3 + 2]; Vector3 side1 = vertices[index1].Position - vertices[index3].Position; Vector3 side2 = vertices[index1].Position - vertices[index2].Position; Vector3 normal = Vector3.Cross(side1, side2); vertices[index1].Normal += normal; vertices[index2].Normal += normal; vertices[index3].Normal += normal; } // Normalize normal vectors for (int i = 0; i < vertices.Length; i++) vertices[i].Normal.Normalize(); return vertices; }
public FoodRenderer(RenderBase rb, FoodManager manager) { RenderBase = rb; Manager = manager; paramsBuffer = new UConstantBuffer(RenderBase, Utilities.SizeOf <Vector4>() * 2); var shaderFlags = #if DEBUG ShaderFlags.Debug; #else ShaderFlags.None; #endif vertexShader = new UVertexShader(RenderBase, "shaders/Vertex_PN_Standard.hlsl", VertexPositionNormal.InputElements); using (var pixelShaderByteCode = ShaderBytecode.CompileFromFile("shaders/Pixel_PC_FishPointLights.hlsl", "main", "ps_4_0", shaderFlags)) pixelShader = new PixelShader(RenderBase.Device, pixelShaderByteCode); vertexBuffer = Buffer.Create(RenderBase.Device, BindFlags.VertexBuffer, //new VertexPositionColor[] { new VertexPositionColor(new Vector3(-0.5f, 0.5f, 0.0f), Color.White), new VertexPositionColor(new Vector3(0.5f, 0.5f, 0.0f), Color.White), new VertexPositionColor(new Vector3(-0.5f, -0.5f, 0.0f), Color.White), // new VertexPositionColor(new Vector3(0.5f, -0.5f, 0.0f), Color.White), new VertexPositionColor(new Vector3(-0.5f, -0.5f, 0.0f), Color.White), new VertexPositionColor(new Vector3(0.5f, 0.5f, 0.0f), Color.White)}); VertexPositionNormal.LoadSTL("models/food.stl", out vertCount)); }
public VertexPositionNormalColor(VertexPositionNormal v, Vector3 color) { this.position = v.position; this.normal = v.normal; this.color = new Vector4(color, 1); }
public static LoadedModels <RealtimeMaterial> LoadRealtimeModelsFromFile(string baseDirectory, string localPath, PostProcessSteps flags = DefaultPostProcessSteps) { string filePath = Path.Combine(baseDirectory, localPath); string[] directoryStructure = localPath.Split('/'); string modelDir = directoryStructure[0]; AssimpContext assimpContext = new AssimpContext(); Assimp.Scene pScene = assimpContext.ImportFile(filePath, flags); //TODO: Identify meshcount for each vertex type. Have to preprocess int meshCount = pScene.MeshCount; var loadedMeshCounts = pScene.GetHenzaiMeshCounts(); int meshCountP = loadedMeshCounts.meshCountP; int meshCountPC = loadedMeshCounts.meshCountPC; int meshCountPN = loadedMeshCounts.meshCountPN; int meshCountPT = loadedMeshCounts.meshCountPT; int meshCountPNT = loadedMeshCounts.meshCountPNT; int meshCountPNTTB = loadedMeshCounts.meshCountPNTTB; Mesh <VertexPosition>[] meshesP = new Mesh <VertexPosition> [meshCountP]; Mesh <VertexPositionColor>[] meshesPC = new Mesh <VertexPositionColor> [meshCountPC]; Mesh <VertexPositionNormal>[] meshesPN = new Mesh <VertexPositionNormal> [meshCountPN]; Mesh <VertexPositionTexture>[] meshesPT = new Mesh <VertexPositionTexture> [meshCountPT]; Mesh <VertexPositionNormalTexture>[] meshesPNT = new Mesh <VertexPositionNormalTexture> [meshCountPNT]; Mesh <VertexPositionNormalTextureTangentBitangent>[] meshesPNTTB = new Mesh <VertexPositionNormalTextureTangentBitangent> [meshCountPNTTB]; RealtimeMaterial[] materialsP = new RealtimeMaterial[meshCountP]; RealtimeMaterial[] materialsPC = new RealtimeMaterial[meshCountPC]; RealtimeMaterial[] materialsPN = new RealtimeMaterial[meshCountPN]; RealtimeMaterial[] materialsPT = new RealtimeMaterial[meshCountPT]; RealtimeMaterial[] materialsPNT = new RealtimeMaterial[meshCountPNT]; RealtimeMaterial[] materialsPNTTB = new RealtimeMaterial[meshCountPNTTB]; ushort[][] meshIndiciesP = new ushort[meshCountP][]; ushort[][] meshIndiciesPC = new ushort[meshCountPC][]; ushort[][] meshIndiciesPN = new ushort[meshCountPN][]; ushort[][] meshIndiciesPT = new ushort[meshCountPT][]; ushort[][] meshIndiciesPNT = new ushort[meshCountPNT][]; ushort[][] meshIndiciesPNTTB = new ushort[meshCountPNTTB][]; int meshIndiciesP_Counter = 0; int meshIndiciesPC_Counter = 0; int meshIndiciesPN_Counter = 0; int meshIndiciesPT_Counter = 0; int meshIndiciesPNT_Counter = 0; int meshIndiciesPNTTB_Counter = 0; var loadedModels = new LoadedModels <RealtimeMaterial>(); VertexPosition[] meshDefinitionP = new VertexPosition[0]; VertexPositionColor[] meshDefinitionPC = new VertexPositionColor[0]; VertexPositionNormal[] meshDefinitionPN = new VertexPositionNormal[0]; VertexPositionTexture[] meshDefinitionPT = new VertexPositionTexture[0]; VertexPositionNormalTexture[] meshDefinitionPNT = new VertexPositionNormalTexture[0]; VertexPositionNormalTextureTangentBitangent[] meshDefinitionPNTTB = new VertexPositionNormalTextureTangentBitangent[0]; for (int i = 0; i < meshCount; i++) { var aiMesh = pScene.Meshes[i]; var vertexCount = aiMesh.VertexCount; if (vertexCount == 0) { Console.Error.WriteLine("Mesh has no verticies"); continue; } Assimp.Material aiMaterial = pScene.Materials[aiMesh.MaterialIndex]; Core.Materials.RealtimeMaterial material = aiMaterial.ToRealtimeMaterial(); VertexRuntimeTypes henzaiVertexType = aiMaterial.ToHenzaiVertexType(); switch (henzaiVertexType) { case VertexRuntimeTypes.VertexPosition: meshDefinitionP = new VertexPosition[vertexCount]; break; case VertexRuntimeTypes.VertexPositionColor: meshDefinitionPC = new VertexPositionColor[vertexCount]; break; case VertexRuntimeTypes.VertexPositionTexture: meshDefinitionPT = new VertexPositionTexture[vertexCount]; break; case VertexRuntimeTypes.VertexPositionNormalTexture: meshDefinitionPNT = new VertexPositionNormalTexture[vertexCount]; break; case VertexRuntimeTypes.VertexPositionNormal: meshDefinitionPN = new VertexPositionNormal[vertexCount]; break; case VertexRuntimeTypes.VertexPositionNormalTextureTangentBitangent: meshDefinitionPNTTB = new VertexPositionNormalTextureTangentBitangent[vertexCount]; break; default: throw new NotImplementedException($"{henzaiVertexType.ToString("g")} not implemented"); } for (int j = 0; j < vertexCount; j++) { byte[] bytes = GenerateVertexBytesArrayFromAssimp(henzaiVertexType, aiMesh, j); switch (henzaiVertexType) { case VertexRuntimeTypes.VertexPosition: meshDefinitionP[j] = ByteMarshal.ByteArrayToStructure <VertexPosition>(bytes); break; case VertexRuntimeTypes.VertexPositionColor: meshDefinitionPC[j] = ByteMarshal.ByteArrayToStructure <VertexPositionColor>(bytes); break; case VertexRuntimeTypes.VertexPositionTexture: meshDefinitionPT[j] = ByteMarshal.ByteArrayToStructure <VertexPositionTexture>(bytes); break; case VertexRuntimeTypes.VertexPositionNormalTexture: meshDefinitionPNT[j] = ByteMarshal.ByteArrayToStructure <VertexPositionNormalTexture>(bytes); break; case VertexRuntimeTypes.VertexPositionNormal: meshDefinitionPN[j] = ByteMarshal.ByteArrayToStructure <VertexPositionNormal>(bytes); break; case VertexRuntimeTypes.VertexPositionNormalTextureTangentBitangent: meshDefinitionPNTTB[j] = ByteMarshal.ByteArrayToStructure <VertexPositionNormalTextureTangentBitangent>(bytes); break; default: throw new NotImplementedException($"{henzaiVertexType.ToString("g")} not implemented"); } } var faceCount = aiMesh.FaceCount; switch (henzaiVertexType) { case VertexRuntimeTypes.VertexPosition: materialsP[meshIndiciesP_Counter] = material; meshIndiciesP[meshIndiciesP_Counter] = new ushort[3 * faceCount]; for (int j = 0; j < faceCount; j++) { var face = aiMesh.Faces[j]; if (face.IndexCount != 3) { Console.Error.WriteLine("Loading Assimp: Face index count != 3!"); continue; } meshIndiciesP[meshIndiciesP_Counter][3 * j + 0] = face.Indices[0].ToUnsignedShort(); meshIndiciesP[meshIndiciesP_Counter][3 * j + 1] = face.Indices[1].ToUnsignedShort(); meshIndiciesP[meshIndiciesP_Counter][3 * j + 2] = face.Indices[2].ToUnsignedShort(); } meshesP[meshIndiciesP_Counter] = new Mesh <VertexPosition>(meshDefinitionP, meshIndiciesP[meshIndiciesP_Counter]); meshIndiciesP_Counter++; break; case VertexRuntimeTypes.VertexPositionColor: materialsPC[meshIndiciesPC_Counter] = material; meshIndiciesPC[meshIndiciesPC_Counter] = new ushort[3 * faceCount]; for (int j = 0; j < faceCount; j++) { var face = aiMesh.Faces[j]; if (face.IndexCount != 3) { Console.Error.WriteLine("Loading Assimp: Face index count != 3!"); continue; } meshIndiciesPC[meshIndiciesPC_Counter][3 * j + 0] = face.Indices[0].ToUnsignedShort(); meshIndiciesPC[meshIndiciesPC_Counter][3 * j + 1] = face.Indices[1].ToUnsignedShort(); meshIndiciesPC[meshIndiciesPC_Counter][3 * j + 2] = face.Indices[2].ToUnsignedShort(); } meshesPC[meshIndiciesPC_Counter] = new Mesh <VertexPositionColor>(meshDefinitionPC, meshIndiciesPC[meshIndiciesPC_Counter]); meshIndiciesPC_Counter++; break; case VertexRuntimeTypes.VertexPositionTexture: materialsPT[meshIndiciesPT_Counter] = material; meshIndiciesPT[meshIndiciesPT_Counter] = new ushort[3 * faceCount]; for (int j = 0; j < faceCount; j++) { var face = aiMesh.Faces[j]; if (face.IndexCount != 3) { Console.Error.WriteLine("Loading Assimp: Face index count != 3!"); continue; } meshIndiciesPT[meshIndiciesPT_Counter][3 * j + 0] = face.Indices[0].ToUnsignedShort(); meshIndiciesPT[meshIndiciesPT_Counter][3 * j + 1] = face.Indices[1].ToUnsignedShort(); meshIndiciesPT[meshIndiciesPT_Counter][3 * j + 2] = face.Indices[2].ToUnsignedShort(); } meshesPT[meshIndiciesPT_Counter] = new Mesh <VertexPositionTexture>(meshDefinitionPT, meshIndiciesPT[meshIndiciesPT_Counter]); meshIndiciesPT_Counter++; break; case VertexRuntimeTypes.VertexPositionNormalTexture: materialsPNT[meshIndiciesPNT_Counter] = material; meshIndiciesPNT[meshIndiciesPNT_Counter] = new ushort[3 * faceCount]; for (int j = 0; j < faceCount; j++) { var face = aiMesh.Faces[j]; if (face.IndexCount != 3) { Console.Error.WriteLine("Loading Assimp: Face index count != 3!"); continue; } meshIndiciesPNT[meshIndiciesPNT_Counter][3 * j + 0] = face.Indices[0].ToUnsignedShort(); meshIndiciesPNT[meshIndiciesPNT_Counter][3 * j + 1] = face.Indices[1].ToUnsignedShort(); meshIndiciesPNT[meshIndiciesPNT_Counter][3 * j + 2] = face.Indices[2].ToUnsignedShort(); } meshesPNT[meshIndiciesPNT_Counter] = new Mesh <VertexPositionNormalTexture>(meshDefinitionPNT, meshIndiciesPNT[meshIndiciesPNT_Counter]); meshIndiciesPNT_Counter++; break; case VertexRuntimeTypes.VertexPositionNormal: materialsPN[meshIndiciesPN_Counter] = material; meshIndiciesPN[meshIndiciesPN_Counter] = new ushort[3 * faceCount]; for (int j = 0; j < faceCount; j++) { var face = aiMesh.Faces[j]; if (face.IndexCount != 3) { Console.Error.WriteLine("Loading Assimp: Face index count != 3!"); continue; } meshIndiciesPN[meshIndiciesPN_Counter][3 * j + 0] = face.Indices[0].ToUnsignedShort(); meshIndiciesPN[meshIndiciesPN_Counter][3 * j + 1] = face.Indices[1].ToUnsignedShort(); meshIndiciesPN[meshIndiciesPN_Counter][3 * j + 2] = face.Indices[2].ToUnsignedShort(); } meshesPN[meshIndiciesPN_Counter] = new Mesh <VertexPositionNormal>(meshDefinitionPN, meshIndiciesPN[meshIndiciesPN_Counter]); meshIndiciesPN_Counter++; break; case VertexRuntimeTypes.VertexPositionNormalTextureTangentBitangent: materialsPNTTB[meshIndiciesPNTTB_Counter] = material; meshIndiciesPNTTB[meshIndiciesPNTTB_Counter] = new ushort[3 * faceCount]; for (int j = 0; j < faceCount; j++) { var face = aiMesh.Faces[j]; if (face.IndexCount != 3) { Console.Error.WriteLine("Loading Assimp: Face index count != 3!"); continue; } meshIndiciesPNTTB[meshIndiciesPNTTB_Counter][3 * j + 0] = face.Indices[0].ToUnsignedShort(); meshIndiciesPNTTB[meshIndiciesPNTTB_Counter][3 * j + 1] = face.Indices[1].ToUnsignedShort(); meshIndiciesPNTTB[meshIndiciesPNTTB_Counter][3 * j + 2] = face.Indices[2].ToUnsignedShort(); } meshesPNTTB[meshIndiciesPNTTB_Counter] = new Mesh <VertexPositionNormalTextureTangentBitangent>(meshDefinitionPNTTB, meshIndiciesPNTTB[meshIndiciesPNTTB_Counter]); meshIndiciesPNTTB_Counter++; break; default: throw new NotImplementedException($"{henzaiVertexType.ToString("g")} not implemented"); } } if (meshCountP > 0) { loadedModels.modelP = new Model <VertexPosition, RealtimeMaterial>(modelDir, meshesP, materialsP); } if (meshCountPC > 0) { loadedModels.modelPC = new Model <VertexPositionColor, RealtimeMaterial>(modelDir, meshesPC, materialsPC); } if (meshCountPN > 0) { loadedModels.modelPN = new Model <VertexPositionNormal, RealtimeMaterial>(modelDir, meshesPN, materialsPN); } if (meshCountPT > 0) { loadedModels.modelPT = new Model <VertexPositionTexture, RealtimeMaterial>(modelDir, meshesPT, materialsPT); } if (meshCountPNT > 0) { loadedModels.modelPNT = new Model <VertexPositionNormalTexture, RealtimeMaterial>(modelDir, meshesPNT, materialsPNT); } if (meshCountPNTTB > 0) { loadedModels.modelPNTTB = new Model <VertexPositionNormalTextureTangentBitangent, RealtimeMaterial>(modelDir, meshesPNTTB, materialsPNTTB); } return(loadedModels); }
protected static int ToPointsBuffer ( Rhino.Geometry.PointCloud pointCloud, Primitive.Part part, out VertexFormatBits vertexFormatBits, out VertexBuffer vb, out int vertexCount, out IndexBuffer ib ) { int pointsCount = part.VertexCount; int normalCount = pointCloud.ContainsNormals ? pointsCount : 0; int colorsCount = pointCloud.ContainsColors ? pointsCount : 0; bool hasPoints = pointsCount > 0; bool hasNormals = normalCount == pointsCount; bool hasColors = colorsCount == pointsCount; if (hasPoints) { if (hasNormals) { if (hasColors) { vertexFormatBits = VertexFormatBits.PositionNormalColored; vb = new VertexBuffer(pointsCount * VertexPositionNormalColored.GetSizeInFloats()); vb.Map(pointsCount * VertexPositionNormalColored.GetSizeInFloats()); using (var vstream = vb.GetVertexStreamPositionNormalColored()) { for (int p = part.StartVertexIndex; p < part.EndVertexIndex; ++p) { var point = pointCloud[p]; var c = new ColorWithTransparency(point.Color.R, point.Color.G, point.Color.B, 255u - point.Color.A); vstream.AddVertex(new VertexPositionNormalColored(RawEncoder.ToHost(point.Location), RawEncoder.ToHost(point.Normal), c)); } } vb.Unmap(); } else { vertexFormatBits = VertexFormatBits.PositionNormal; vb = new VertexBuffer(pointsCount * VertexPositionNormal.GetSizeInFloats()); vb.Map(pointsCount * VertexPositionNormal.GetSizeInFloats()); using (var vstream = vb.GetVertexStreamPositionNormal()) { for (int p = part.StartVertexIndex; p < part.EndVertexIndex; ++p) { var point = pointCloud[p]; vstream.AddVertex(new VertexPositionNormal(RawEncoder.ToHost(point.Location), RawEncoder.ToHost(point.Normal))); } } vb.Unmap(); } } else { if (hasColors) { vertexFormatBits = VertexFormatBits.PositionColored; vb = new VertexBuffer(pointsCount * VertexPositionColored.GetSizeInFloats()); vb.Map(pointsCount * VertexPositionColored.GetSizeInFloats()); using (var vstream = vb.GetVertexStreamPositionColored()) { for (int p = part.StartVertexIndex; p < part.EndVertexIndex; ++p) { var point = pointCloud[p]; var c = new ColorWithTransparency(point.Color.R, point.Color.G, point.Color.B, 255u - point.Color.A); vstream.AddVertex(new VertexPositionColored(RawEncoder.ToHost(point.Location), c)); } } vb.Unmap(); } else { vertexFormatBits = VertexFormatBits.Position; vb = new VertexBuffer(pointsCount * VertexPosition.GetSizeInFloats()); vb.Map(pointsCount * VertexPosition.GetSizeInFloats()); using (var vstream = vb.GetVertexStreamPosition()) { for (int p = part.StartVertexIndex; p < part.EndVertexIndex; ++p) { var point = pointCloud[p]; vstream.AddVertex(new VertexPosition(RawEncoder.ToHost(point.Location))); } } vb.Unmap(); } } ib = IndexPointsBuffer(pointsCount); } else { vertexFormatBits = 0; vb = null; ib = null; } vertexCount = pointsCount; return(pointsCount); }
/// <summary> /// Returns a Sphere Mesh with the corresponing vertex struct. /// </summary> public static Mesh <VertexPositionNormal> GenerateSphereNormal(int numLatitudeLines, int numLongitudeLines, float radius) { // One vertex at every latitude-longitude intersection, // plus one for the north pole and one for the south. // One meridian serves as a UV seam, so we double the vertices there. int numVertices = numLatitudeLines * (numLongitudeLines + 1) + 2; VertexPositionNormal[] vertices = new VertexPositionNormal[numVertices]; Vector2[] SphereParamters = new Vector2[numVertices]; List <ushort> indices = new List <ushort>(); // North pole. vertices[0].Position = new Vector3(0, radius, 0); // South pole. vertices[numVertices - 1].Position = new Vector3(0, -radius, 0); SphereParamters[numVertices - 1] = new Vector2(0, 1); // +1.0f because there's a gap between the poles and the first parallel. float latitudeSpacing = 1.0f / (numLatitudeLines + 1.0f); float longitudeSpacing = 1.0f / (numLongitudeLines); // start writing new vertices at position 1 int v = 1; for (int latitude = 0; latitude < numLatitudeLines; latitude++) { for (int longitude = 0; longitude <= numLongitudeLines; longitude++) { // Scale coordinates into the 0...1 texture coordinate range, // with north at the top (y = 0). SphereParamters[v] = new Vector2( longitude.ToFloat() * longitudeSpacing, (latitude.ToFloat() + 1.0f) * latitudeSpacing ); // Convert to spherical coordinates: // theta is a longitude angle (around the equator) in radians. // phi is a latitude angle (north or south of the equator). float theta = SphereParamters[v].X * 2.0f * Math.PI.ToFloat(); float phi = SphereParamters[v].Y * Math.PI.ToFloat(); // This determines the radius of the ring of this line of latitude. // It's widest at the equator, and narrows as phi increases/decreases. // float c = Math.Sin(phi).ToFloat(); // Usual formula for a vector in spherical coordinates. // You can exchange x & z to wind the opposite way around the sphere. vertices[v].Position = new Vector3( Math.Sin(phi).ToFloat() * Math.Sin(theta).ToFloat(), Math.Cos(phi).ToFloat(), Math.Sin(phi).ToFloat() * Math.Cos(theta).ToFloat() ) * radius; vertices[v].Normal = Vector3.Normalize(vertices[v].Position); if (latitude < numLatitudeLines - 1) { indices.Add(v.ToUnsignedShort()); indices.Add((v + 1).ToUnsignedShort()); indices.Add((v + 1 + numLongitudeLines).ToUnsignedShort()); indices.Add((v + 1).ToUnsignedShort()); indices.Add((v + 2 + numLongitudeLines).ToUnsignedShort()); indices.Add((v + numLongitudeLines + 1).ToUnsignedShort()); } // Proceed to the next vertex. v++; } } // North pole indices for (int longitude = 1; longitude < numLongitudeLines; longitude++) { indices.Add(0); indices.Add((longitude + 1).ToUnsignedShort()); indices.Add(longitude.ToUnsignedShort()); } indices.Add(0); indices.Add(1); indices.Add(numLongitudeLines.ToUnsignedShort()); v -= numLongitudeLines + 1; // southpole for (int longitude = 0; longitude <= numLongitudeLines; longitude++) { indices.Add((v + longitude).ToUnsignedShort()); indices.Add((v + longitude + 1).ToUnsignedShort()); indices.Add((numVertices - 1).ToUnsignedShort()); } indices.Add((numVertices - 2).ToUnsignedShort()); indices.Add((v + 1).ToUnsignedShort()); indices.Add((numVertices - 1).ToUnsignedShort()); return(new Mesh <VertexPositionNormal>(vertices, indices.ToArray())); }
protected static VertexBuffer ToVertexBuffer ( Rhino.Geometry.Mesh mesh, Primitive.Part part, out VertexFormatBits vertexFormatBits, System.Drawing.Color color = default ) { int verticesCount = part.EndVertexIndex - part.StartVertexIndex; int normalCount = mesh.Normals.Count == mesh.Vertices.Count ? verticesCount : 0; int colorsCount = color.IsEmpty ? (mesh.VertexColors.Count == mesh.Vertices.Count ? verticesCount : 0) : verticesCount; bool hasVertices = verticesCount > 0; bool hasNormals = normalCount > 0; bool hasColors = colorsCount > 0; if (hasVertices) { var vertices = mesh.Vertices; if (hasNormals) { var normals = mesh.Normals; if (hasColors) { vertexFormatBits = VertexFormatBits.PositionNormalColored; var colors = mesh.VertexColors; var vb = new VertexBuffer(verticesCount * VertexPositionNormalColored.GetSizeInFloats()); vb.Map(verticesCount * VertexPositionNormalColored.GetSizeInFloats()); using (var stream = vb.GetVertexStreamPositionNormalColored()) { for (int v = part.StartVertexIndex; v < part.EndVertexIndex; ++v) { var c = !color.IsEmpty ? color : colors[v]; uint T = Math.Max(1, 255u - c.A); stream.AddVertex(new VertexPositionNormalColored(RawEncoder.ToHost(vertices[v]), RawEncoder.ToHost(normals[v]), new ColorWithTransparency(c.R, c.G, c.B, T))); } } vb.Unmap(); return(vb); } else { vertexFormatBits = VertexFormatBits.PositionNormal; var vb = new VertexBuffer(verticesCount * VertexPositionNormal.GetSizeInFloats()); vb.Map(verticesCount * VertexPositionNormal.GetSizeInFloats()); using (var stream = vb.GetVertexStreamPositionNormal()) { for (int v = part.StartVertexIndex; v < part.EndVertexIndex; ++v) { stream.AddVertex(new VertexPositionNormal(RawEncoder.ToHost(vertices[v]), RawEncoder.ToHost(normals[v]))); } } vb.Unmap(); return(vb); } } else { if (hasColors) { vertexFormatBits = VertexFormatBits.PositionColored; var colors = mesh.VertexColors; var vb = new VertexBuffer(verticesCount * VertexPositionColored.GetSizeInFloats()); vb.Map(verticesCount * VertexPositionColored.GetSizeInFloats()); using (var stream = vb.GetVertexStreamPositionColored()) { for (int v = part.StartVertexIndex; v < part.EndVertexIndex; ++v) { var c = !color.IsEmpty ? color : colors[v]; uint T = Math.Max(1, 255u - c.A); stream.AddVertex(new VertexPositionColored(RawEncoder.ToHost(vertices[v]), new ColorWithTransparency(c.R, c.G, c.B, T))); } } vb.Unmap(); return(vb); } else { vertexFormatBits = VertexFormatBits.Position; var vb = new VertexBuffer(verticesCount * VertexPosition.GetSizeInFloats()); vb.Map(verticesCount * VertexPosition.GetSizeInFloats()); using (var stream = vb.GetVertexStreamPosition()) { for (int v = part.StartVertexIndex; v < part.EndVertexIndex; ++v) { stream.AddVertex(new VertexPosition(RawEncoder.ToHost(vertices[v]))); } } vb.Unmap(); return(vb); } } } vertexFormatBits = 0; return(null); }
public static VertexPositionNormal[] GenerateCone(float height, float bottomRadius, float topRadius, int numSides) { int nbHeightSeg = 1; // Not implemented yet int nbVerticesCap = numSides + 1; #region Vertices // bottom + top + sides Vector3[] vertices = new Vector3[nbVerticesCap + nbVerticesCap + numSides * nbHeightSeg * 2 + 2]; int vert = 0; float _2pi = (float)Math.PI * 2f; // Bottom cap vertices[vert++] = new Vector3(0f, 0f, 0f); while (vert <= numSides) { float rad = (float)vert / numSides * _2pi; vertices[vert] = new Vector3((float)Math.Cos(rad) * bottomRadius, 0f, (float)Math.Sin(rad) * bottomRadius); vert++; } // Top cap vertices[vert++] = new Vector3(0f, height, 0f); while (vert <= numSides * 2 + 1) { float rad = (float)(vert - numSides - 1) / numSides * _2pi; vertices[vert] = new Vector3((float)Math.Cos(rad) * topRadius, height, (float)Math.Sin(rad) * topRadius); vert++; } // Sides int v = 0; while (vert <= vertices.Length - 4) { float rad = (float)v / numSides * _2pi; vertices[vert] = new Vector3((float)Math.Cos(rad) * topRadius, height, (float)Math.Sin(rad) * topRadius); vertices[vert + 1] = new Vector3((float)Math.Cos(rad) * bottomRadius, 0, (float)Math.Sin(rad) * bottomRadius); vert += 2; v++; } vertices[vert] = vertices[numSides * 2 + 2]; vertices[vert + 1] = vertices[numSides * 2 + 3]; #endregion #region Normals // bottom + top + sides Vector3[] normals = new Vector3[vertices.Length]; vert = 0; // Bottom cap while (vert <= numSides) { normals[vert++] = Vector3Helper.Down; } // Top cap while (vert <= numSides * 2 + 1) { normals[vert++] = Vector3Helper.Up; } // Sides v = 0; while (vert <= vertices.Length - 4) { float rad = (float)v / numSides * _2pi; float cos = (float)Math.Cos(rad); float sin = (float)Math.Sin(rad); normals[vert] = new Vector3(cos, 0f, sin); normals[vert + 1] = normals[vert]; vert += 2; v++; } normals[vert] = normals[numSides * 2 + 2]; normals[vert + 1] = normals[numSides * 2 + 3]; #endregion #region UVs Vector2[] uvs = new Vector2[vertices.Length]; // Bottom cap int u = 0; uvs[u++] = new Vector2(0.5f, 0.5f); while (u <= numSides) { float rad = (float)u / numSides * _2pi; uvs[u] = new Vector2((float)Math.Cos(rad) * .5f + .5f, (float)Math.Sin(rad) * .5f + .5f); u++; } // Top cap uvs[u++] = new Vector2(0.5f, 0.5f); while (u <= numSides * 2 + 1) { float rad = (float)u / numSides * _2pi; uvs[u] = new Vector2((float)Math.Cos(rad) * .5f + .5f, (float)Math.Sin(rad) * .5f + .5f); u++; } // Sides int u_sides = 0; while (u <= uvs.Length - 4) { float t = (float)u_sides / numSides; uvs[u] = new Vector2(t, 1f); uvs[u + 1] = new Vector2(t, 0f); u += 2; u_sides++; } uvs[u] = new Vector2(1f, 1f); uvs[u + 1] = new Vector2(1f, 0f); #endregion #region Indices int nbTriangles = numSides + numSides + numSides * 2; int[] indices = new int[nbTriangles * 3 + 3]; // Bottom cap int tri = 0; int i = 0; while (tri < numSides - 1) { indices[i] = 0; indices[i + 1] = tri + 1; indices[i + 2] = tri + 2; tri++; i += 3; } indices[i] = 0; indices[i + 1] = tri + 1; indices[i + 2] = 1; tri++; i += 3; // Top cap //tri++; while (tri < numSides * 2) { indices[i] = tri + 2; indices[i + 1] = tri + 1; indices[i + 2] = nbVerticesCap; tri++; i += 3; } indices[i] = nbVerticesCap + 1; indices[i + 1] = tri + 1; indices[i + 2] = nbVerticesCap; tri++; i += 3; tri++; // Sides while (tri <= nbTriangles) { indices[i] = tri + 2; indices[i + 1] = tri + 1; indices[i + 2] = tri + 0; tri++; i += 3; indices[i] = tri + 1; indices[i + 1] = tri + 2; indices[i + 2] = tri + 0; tri++; i += 3; } #endregion var verticesOut = new VertexPositionNormal[indices.Length]; for (int j = 0; j < indices.Length; j++) { var index = indices[j]; verticesOut[j] = new VertexPositionNormal { Position = vertices[index], Normal = normals[index], //TexCoord = uvs[index] }; } return(verticesOut); }
public FishRenderer(RenderBase rb, FishManager manager) { RenderBase = rb; Manager = manager; paramsBuffer = new UConstantBuffer(RenderBase, Utilities.SizeOf <Vector4>() * 2); var shaderFlags = #if DEBUG ShaderFlags.Debug; #else ShaderFlags.None; #endif vertexShader = new UVertexShader(RenderBase, "shaders/Vertex_PC_Explode.hlsl", VertexPositionNormal.InputElements); using (var pixelShaderByteCode = ShaderBytecode.CompileFromFile("shaders/Pixel_PC_FishPointLights.hlsl", "main", "ps_4_0", shaderFlags)) pixelShader = new PixelShader(RenderBase.Device, pixelShaderByteCode); vertexBuffer = new Buffer[3]; vertexCount = new int[vertexBuffer.Length]; vertexBuffer[0] = Buffer.Create(RenderBase.Device, BindFlags.VertexBuffer, VertexPositionNormal.LoadSTL("models/fish.stl", out vertexCount[0])); vertexBuffer[1] = Buffer.Create(RenderBase.Device, BindFlags.VertexBuffer, VertexPositionNormal.LoadSTL("models/fish4.stl", out vertexCount[1])); vertexBuffer[2] = Buffer.Create(RenderBase.Device, BindFlags.VertexBuffer, VertexPositionNormal.LoadSTL("models/fish5.stl", out vertexCount[2])); coneVertexBuffer = Buffer.Create(RenderBase.Device, BindFlags.VertexBuffer, new VertexPositionColor[] { new VertexPositionColor(new Vector3(0.0f, 0.0f, 0.0f), Color.White), new VertexPositionColor(new Vector3(1.0f, 1.0f, 0.0f), Color.White), new VertexPositionColor(new Vector3(1.0f, -1.0f, 0.0f), Color.White) }); }
private static CustomMesh CreateShape(float xDim, float yDim, float zDim) { // Create a primitive mesh for creating our custom pyramid shape CustomMesh pyramid = new CustomMesh(); // Even though we really need 5 vertices to create a pyramid shape, since // we want to assign different normals for points with same position to have // more accurate lighting effect, we will use 16 vertices. VertexPositionNormal[] verts = new VertexPositionNormal[16]; Vector3 vBase0 = new Vector3(-xDim / 2, 0, zDim / 2); Vector3 vBase1 = new Vector3(xDim / 2, 0, zDim / 2); Vector3 vBase2 = new Vector3(xDim / 2, 0, -zDim / 2); Vector3 vBase3 = new Vector3(-xDim / 2, 0, -zDim / 2); Vector3 vTop = new Vector3(0, yDim, 0); verts[0].Position = vTop; verts[1].Position = vBase1; verts[2].Position = vBase0; verts[3].Position = vTop; verts[4].Position = vBase2; verts[5].Position = vBase1; verts[6].Position = vTop; verts[7].Position = vBase3; verts[8].Position = vBase2; verts[9].Position = vTop; verts[10].Position = vBase0; verts[11].Position = vBase3; verts[12].Position = vBase0; verts[13].Position = vBase1; verts[14].Position = vBase2; verts[15].Position = vBase3; verts[0].Normal = verts[1].Normal = verts[2].Normal = CalcNormal(vTop, vBase1, vBase0); verts[3].Normal = verts[4].Normal = verts[5].Normal = CalcNormal(vTop, vBase2, vBase1); verts[6].Normal = verts[7].Normal = verts[8].Normal = CalcNormal(vTop, vBase3, vBase2); verts[9].Normal = verts[10].Normal = verts[11].Normal = CalcNormal(vTop, vBase0, vBase3); verts[12].Normal = verts[13].Normal = verts[14].Normal = verts[15].Normal = CalcNormal(vBase0, vBase1, vBase3); pyramid.VertexBuffer = new VertexBuffer(State.Device, typeof(VertexPositionNormal), 16, BufferUsage.None); pyramid.VertexDeclaration = VertexPositionNormal.VertexDeclaration; pyramid.VertexBuffer.SetData(verts); pyramid.NumberOfVertices = 16; short[] indices = new short[18]; indices[0] = 0; indices[1] = 1; indices[2] = 2; indices[3] = 3; indices[4] = 4; indices[5] = 5; indices[6] = 6; indices[7] = 7; indices[8] = 8; indices[9] = 9; indices[10] = 10; indices[11] = 11; indices[12] = 12; indices[13] = 13; indices[14] = 15; indices[15] = 13; indices[16] = 14; indices[17] = 15; pyramid.IndexBuffer = new IndexBuffer(State.Device, typeof(short), 18, BufferUsage.WriteOnly); pyramid.IndexBuffer.SetData(indices); pyramid.PrimitiveType = PrimitiveType.TriangleList; pyramid.NumberOfPrimitives = 6; return(pyramid); }
public VMeshData(byte[] data, ILibFile materialLibrary, string name) { if (data == null) { throw new ArgumentNullException("data"); } if (materialLibrary == null) { throw new ArgumentNullException("materialLibrary"); } vmsname = name; ready = false; using (BinaryReader reader = new BinaryReader(new MemoryStream(data))) { // Read the data header. MeshType = reader.ReadUInt32(); SurfaceType = reader.ReadUInt32(); MeshCount = reader.ReadUInt16(); IndexCount = reader.ReadUInt16(); FlexibleVertexFormat = (D3DFVF)reader.ReadUInt16(); VertexCount = reader.ReadUInt16(); // Read the mesh headers. Meshes = new List <TMeshHeader>(); int triangleStartOffset = 0; for (int count = 0; count < MeshCount; count++) { TMeshHeader item = new TMeshHeader(reader, triangleStartOffset, materialLibrary); triangleStartOffset += item.NumRefVertices; Meshes.Add(item); } // Read the triangle data Indices = new ushort[IndexCount]; for (int i = 0; i < IndexCount; i++) { Indices[i] = reader.ReadUInt16(); } // Read the vertex data. // The FVF defines what fields are included for each vertex. switch (FlexibleVertexFormat) { case D3DFVF.XYZ: //(D3DFVF)0x0002: verticesVertexPosition = new VertexPosition[VertexCount]; for (int i = 0; i < VertexCount; i++) { verticesVertexPosition[i] = new VertexPosition(reader); } break; case D3DFVF.XYZ | D3DFVF.NORMAL: //(D3DFVF)0x0012: verticesVertexPositionNormal = new VertexPositionNormal[VertexCount]; for (int i = 0; i < VertexCount; i++) { verticesVertexPositionNormal[i] = new VertexPositionNormal(reader); } break; case D3DFVF.XYZ | D3DFVF.TEX1: //(D3DFVF)0x0102: verticesVertexPositionNormalTexture = new VertexPositionNormalTexture[VertexCount]; for (int i = 0; i < VertexCount; i++) { Vector3 position = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Vector2 textureCoordinate = new Vector2(reader.ReadSingle(), 1 - reader.ReadSingle()); verticesVertexPositionNormalTexture[i] = new VertexPositionNormalTexture(position, Vector3.Zero, textureCoordinate); } CalculateNormals(verticesVertexPositionNormalTexture); FlexibleVertexFormat |= D3DFVF.NORMAL; break; case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.TEX1: //(D3DFVF)0x0112: verticesVertexPositionNormalTexture = new VertexPositionNormalTexture[VertexCount]; for (int i = 0; i < VertexCount; i++) { Vector3 position = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Vector3 normal = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Vector2 textureCoordinate = new Vector2(reader.ReadSingle(), 1 - reader.ReadSingle()); verticesVertexPositionNormalTexture[i] = new VertexPositionNormalTexture(position, normal, textureCoordinate); } break; case D3DFVF.XYZ | D3DFVF.DIFFUSE | D3DFVF.TEX1: //(D3DFVF)0x0142: verticesVertexPositionNormalColorTexture = new VertexPositionNormalColorTexture[VertexCount]; for (int i = 0; i < VertexCount; i++) { Vector3 position = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); int r = reader.ReadByte(); int g = reader.ReadByte(); int b = reader.ReadByte(); int a = reader.ReadByte(); Color4 diffuse = new Color4(r / 255f, g / 255f, b / 255f, a / 255f); Vector2 textureCoordinate = new Vector2(reader.ReadSingle(), 1 - reader.ReadSingle()); verticesVertexPositionNormalColorTexture[i] = new VertexPositionNormalColorTexture(position, Vector3.Zero, diffuse, textureCoordinate); } FlexibleVertexFormat |= D3DFVF.NORMAL; CalculateNormals(verticesVertexPositionNormalColorTexture); break; case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.DIFFUSE | D3DFVF.TEX1: //(D3DFVF)0x0152: verticesVertexPositionNormalColorTexture = new VertexPositionNormalColorTexture[VertexCount]; for (int i = 0; i < VertexCount; i++) { //verticesVertexPositionNormalDiffuseTexture[i] = new VertexPositionNormalDiffuseTexture(reader); var position = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); var normal = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); int r = reader.ReadByte(); int g = reader.ReadByte(); int b = reader.ReadByte(); int a = reader.ReadByte(); Color4 diffuse = new Color4(r / 255f, g / 255f, b / 255f, a / 255f); Vector2 textureCoordinate = new Vector2(reader.ReadSingle(), 1 - reader.ReadSingle()); verticesVertexPositionNormalColorTexture[i] = new VertexPositionNormalColorTexture(position, normal, diffuse, textureCoordinate); } break; case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.TEX2: //(D3DFVF)0x0212: verticesVertexPositionNormalTextureTwo = new VertexPositionNormalTextureTwo[VertexCount]; for (int i = 0; i < VertexCount; i++) { verticesVertexPositionNormalTextureTwo[i] = new VertexPositionNormalTextureTwo(reader); } break; case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.DIFFUSE | D3DFVF.TEX2: //(D3DFVF)0x0252: verticesVertexPositionNormalDiffuseTextureTwo = new VertexPositionNormalDiffuseTextureTwo[VertexCount]; for (int i = 0; i < VertexCount; i++) { verticesVertexPositionNormalDiffuseTextureTwo[i] = new VertexPositionNormalDiffuseTextureTwo(reader); } break; /*case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.TEX4: //(D3DFVF)0x0412: * for (int i = 0; i < VertexCount; i++) vertices[i] = new VertexPositionNormalTextureTangentBinormal(reader); * break;*/ default: throw new FileContentException("UTF:VMeshData", "FVF 0x" + FlexibleVertexFormat + " not supported."); } } }
public VMeshData(ArraySegment <byte> data, ILibFile materialLibrary, string name) { if (data == null) { throw new ArgumentNullException("data"); } if (materialLibrary == null) { throw new ArgumentNullException("materialLibrary"); } vmsname = name; ready = false; using (BinaryReader reader = new BinaryReader(data.GetReadStream())) { // Read the data header. MeshType = reader.ReadUInt32(); SurfaceType = reader.ReadUInt32(); MeshCount = reader.ReadUInt16(); IndexCount = reader.ReadUInt16(); FlexibleVertexFormat = (D3DFVF)reader.ReadUInt16(); OriginalFVF = FlexibleVertexFormat; VertexCount = reader.ReadUInt16(); // Read the mesh headers. Meshes = new List <TMeshHeader>(); int triangleStartOffset = 0; for (int count = 0; count < MeshCount; count++) { TMeshHeader item = new TMeshHeader(reader, triangleStartOffset, materialLibrary); if (item.NumRefVertices < 3) { FLLog.Warning("Vms", $"{name} mesh {count} references 0 triangles"); } triangleStartOffset += item.NumRefVertices; Meshes.Add(item); } // Read the triangle data Indices = new ushort[IndexCount]; for (int i = 0; i < IndexCount; i++) { Indices[i] = reader.ReadUInt16(); } // Read the vertex data. // The FVF defines what fields are included for each vertex. switch (FlexibleVertexFormat) { case D3DFVF.XYZ: //(D3DFVF)0x0002: verticesVertexPosition = new VertexPosition[VertexCount]; for (int i = 0; i < VertexCount; i++) { verticesVertexPosition[i] = new VertexPosition(reader); } break; case D3DFVF.XYZ | D3DFVF.NORMAL: //(D3DFVF)0x0012: verticesVertexPositionNormal = new VertexPositionNormal[VertexCount]; for (int i = 0; i < VertexCount; i++) { verticesVertexPositionNormal[i] = new VertexPositionNormal(reader); } break; case D3DFVF.XYZ | D3DFVF.TEX1: //(D3DFVF)0x0102: verticesVertexPositionNormalTexture = new VertexPositionNormalTexture[VertexCount]; for (int i = 0; i < VertexCount; i++) { Vector3 position = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Vector2 textureCoordinate = new Vector2(reader.ReadSingle(), 1 - reader.ReadSingle()); verticesVertexPositionNormalTexture[i] = new VertexPositionNormalTexture(position, Vector3.One, textureCoordinate); } FlexibleVertexFormat |= D3DFVF.NORMAL; break; case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.TEX1: //(D3DFVF)0x0112: verticesVertexPositionNormalTexture = new VertexPositionNormalTexture[VertexCount]; for (int i = 0; i < VertexCount; i++) { Vector3 position = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Vector3 normal = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Vector2 textureCoordinate = new Vector2(reader.ReadSingle(), 1 - reader.ReadSingle()); verticesVertexPositionNormalTexture[i] = new VertexPositionNormalTexture(position, normal, textureCoordinate); } break; case D3DFVF.XYZ | D3DFVF.DIFFUSE | D3DFVF.TEX1: //(D3DFVF)0x0142: verticesVertexPositionNormalDiffuseTexture = new VertexPositionNormalDiffuseTexture[VertexCount]; Diffuse = new uint[VertexCount]; for (int i = 0; i < VertexCount; i++) { Vector3 position = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Diffuse[i] = reader.ReadUInt32(); Vector2 textureCoordinate = new Vector2(reader.ReadSingle(), 1 - reader.ReadSingle()); verticesVertexPositionNormalDiffuseTexture[i] = new VertexPositionNormalDiffuseTexture(position, Vector3.One, Diffuse[i], textureCoordinate); } FlexibleVertexFormat |= D3DFVF.NORMAL; break; case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.DIFFUSE | D3DFVF.TEX1: //(D3DFVF)0x0152: verticesVertexPositionNormalDiffuseTexture = new VertexPositionNormalDiffuseTexture[VertexCount]; Diffuse = new uint[VertexCount]; for (int i = 0; i < VertexCount; i++) { var position = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); var normal = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Diffuse[i] = reader.ReadUInt32(); Vector2 textureCoordinate = new Vector2(reader.ReadSingle(), 1 - reader.ReadSingle()); verticesVertexPositionNormalDiffuseTexture[i] = new VertexPositionNormalDiffuseTexture(position, normal, Diffuse[i], textureCoordinate); } break; case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.TEX2: //(D3DFVF)0x0212: verticesVertexPositionNormalTextureTwo = new VertexPositionNormalTextureTwo[VertexCount]; for (int i = 0; i < VertexCount; i++) { verticesVertexPositionNormalTextureTwo[i] = new VertexPositionNormalTextureTwo(reader); } break; case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.DIFFUSE | D3DFVF.TEX2: //(D3DFVF)0x0252: verticesVertexPositionNormalDiffuseTextureTwo = new VertexPositionNormalDiffuseTextureTwo[VertexCount]; for (int i = 0; i < VertexCount; i++) { verticesVertexPositionNormalDiffuseTextureTwo[i] = new VertexPositionNormalDiffuseTextureTwo(reader); } break; /*case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.TEX4: //(D3DFVF)0x0412: * for (int i = 0; i < VertexCount; i++) vertices[i] = new VertexPositionNormalTextureTangentBinormal(reader); * break;*/ default: throw new FileContentException("UTF:VMeshData", "FVF 0x" + FlexibleVertexFormat + " not supported."); } } }
/// <summary> /// Adds a new vertex to the primitive model. This should only be called /// during the initialization process, before InitializePrimitive. /// </summary> protected void AddVertex(Vector3 position, Vector3 normal) { var vertElement = new VertexPositionNormal(position, normal); vertices.Add(vertElement); }