public static library_geometries MakeGeometryLibrary(ref Model3D mdl) { library_geometries lib_geo = new library_geometries(); //lib_geo.id = "lib_geo"; ulong len = (ulong)mdl.builder.TextureImages.Count; geometry geo = new geometry(); //for (ulong i = 0; i < len; i++) //{ geo = new geometry(); geo.id = "geometry"; mesh m = new mesh(); m.source = new source[] { makePositionsSource(ref mdl), makeTexCoordSource(ref mdl), makeColorSource(ref mdl) }; m.vertices = MakeVertices(); List <object> polyLists = new List <object>(); uint indices_offset = 0; for (ulong i = 0; i < len; i++) { polyLists.Add(MakePolyList(i, mdl.meshes[(int)i].indices, ref indices_offset)); //indices_offset += (uint)mdl.meshes[(int)i].indices.LongLength; } m.Items = polyLists.ToArray(); geo.Item = m; lib_geo.geometry = new geometry[] { geo }; return(lib_geo); }
private static STGenericMesh LoadMeshData(ColladaScene scene, Node node, geometry geom, library_materials materials, controller controller = null) { mesh daeMesh = geom.Item as mesh; STGenericMesh mesh = new STGenericMesh(); mesh.Vertices = new List <STVertex>(); mesh.Name = geom.name; var boneWeights = ParseWeightController(controller, scene); foreach (var item in daeMesh.Items) { //Poly lists can control specific amounts of indices for primitive types like quads if (item is polylist) { var poly = item as polylist; ConvertPolygon(scene, mesh, daeMesh, poly.input, boneWeights, materials, poly.material, poly.p, (int)poly.count, poly.vcount); } else if (item is triangles) { var triangle = item as triangles; ConvertPolygon(scene, mesh, daeMesh, triangle.input, boneWeights, materials, triangle.material, triangle.p, (int)triangle.count); } } return(mesh); }
private DivinityModelType FindDivModelType(mesh mesh) { var technique = FindExporterExtraData(mesh.extra); if (technique != null) { if (technique.Any != null) { foreach (var setting in technique.Any) { if (setting.LocalName == "DivModelType") { switch (setting.InnerText.Trim()) { case "Normal": return(DivinityModelType.Normal); case "Cloth": return(DivinityModelType.Cloth); case "Rigid": return(DivinityModelType.Rigid); case "MeshProxy": return(DivinityModelType.MeshProxy); default: Utils.Warn($"Unrecognized model type in <DivModelType> tag: {setting.Value}"); break; } } } } } return(DivinityModelType.Undefined); }
// Use this for initialization void Start() { for (int i = 0; i < ClusterAmount; i++) { mesh group = new mesh(); Cluster.Add(group); } }
private Mesh ImportMesh(geometry geom, mesh mesh, VertexDescriptor vertexFormat) { var collada = new ColladaMesh(); bool isSkinned = SkinnedMeshes.Contains(geom.id); collada.ImportFromCollada(mesh, vertexFormat, isSkinned, Options); var m = new Mesh(); m.VertexFormat = collada.InternalVertexType; m.Name = "Unnamed"; m.PrimaryVertexData = new VertexData(); m.PrimaryVertexData.Vertices = collada.ConsolidatedVertices; if (!Options.StripMetadata) { var components = m.VertexFormat.ComponentNames().Select(s => new GrannyString(s)).ToList(); m.PrimaryVertexData.VertexComponentNames = components; } else { m.PrimaryVertexData.VertexComponentNames = null; } m.PrimaryTopology = new TriTopology(); m.PrimaryTopology.Indices = collada.ConsolidatedIndices; m.PrimaryTopology.Groups = new List <TriTopologyGroup>(); var triGroup = new TriTopologyGroup(); triGroup.MaterialIndex = 0; triGroup.TriFirst = 0; triGroup.TriCount = collada.TriangleCount; m.PrimaryTopology.Groups.Add(triGroup); m.MaterialBindings = new List <MaterialBinding>(); m.MaterialBindings.Add(new MaterialBinding()); // m.BoneBindings; - TODO m.OriginalToConsolidatedVertexIndexMap = collada.OriginalToConsolidatedVertexIndexMap; var divModelType = FindDivModelType(mesh); if (divModelType != 0) { m.ModelType = divModelType; m.HasDefiniteModelType = true; } Utils.Info(String.Format("Imported {0} mesh ({1} tri groups, {2} tris)", (m.VertexFormat.HasBoneWeights ? "skinned" : "rigid"), m.PrimaryTopology.Groups.Count, collada.TriangleCount)); return(m); }
private Mesh ImportMesh(string name, mesh mesh, string vertexFormat) { var m = Mesh.ImportFromCollada(mesh, vertexFormat, Options.RecalculateNormals, Options.RecalculateTangents); m.Name = name; VertexDatas.Add(m.PrimaryVertexData); TriTopologies.Add(m.PrimaryTopology); Meshes.Add(m); return(m); }
private Mesh ImportMesh(Root root, string name, geometry geom, mesh mesh, VertexDescriptor vertexFormat) { var m = ImportMesh(geom, mesh, vertexFormat); m.Name = name; root.VertexDatas.Add(m.PrimaryVertexData); root.TriTopologies.Add(m.PrimaryTopology); root.Meshes.Add(m); return(m); }
private void LoadGeometryFromCollada(CollisionGroupNode parent, geometry geo) { mesh m = geo.Item as mesh; // For safety, read the model's definition of where the position data is // and grab it from there. We could just do a search for "position" in the // source list names, but this makes sure there are no errors. InputLocal pos_input = Array.Find(m.vertices.input, x => x.semantic == "POSITION"); source pos_src = Array.Find(m.source, x => x.id == pos_input.source.Trim('#')); float_array pos_arr = pos_src.Item as float_array; // For some reason Maya puts a leading space in the face index data, // so we need to trim that out before trying to parse the index string. triangles tris = m.Items[0] as triangles; string[] indices = tris.p.Trim(' ').Split(' '); int stride = tris.input.Length; // Make sure this tool can support meshes with multiple vertex attributes. for (int i = 0; i < indices.Length; i += stride * 3) { int vec1_index = Convert.ToInt32(indices[i]); int vec2_index = Convert.ToInt32(indices[i + stride]); int vec3_index = Convert.ToInt32(indices[i + (stride * 2)]); Vector3 vec1 = new Vector3((float)pos_arr.Values[vec1_index * 3], (float)pos_arr.Values[(vec1_index * 3) + 1], (float)pos_arr.Values[(vec1_index * 3) + 2]); Vector3 vec2 = new Vector3((float)pos_arr.Values[vec2_index * 3], (float)pos_arr.Values[(vec2_index * 3) + 1], (float)pos_arr.Values[(vec2_index * 3) + 2]); Vector3 vec3 = new Vector3((float)pos_arr.Values[vec3_index * 3], (float)pos_arr.Values[(vec3_index * 3) + 1], (float)pos_arr.Values[(vec3_index * 3) + 2]); // The benefit of using this library is that we easily got the up-axis // info from the file. If the up-axis was defined as Z-up, we need to // swap the Y and Z components of our vectors so the mesh isn't sideways. // (The Wind Waker is Y-up.) if (m_UpAxis == UpAxisType.Z_UP) { vec1 = SwapYZ(vec1); vec2 = SwapYZ(vec2); vec3 = SwapYZ(vec3); } CollisionTriangle new_tri = new CollisionTriangle(vec1, vec2, vec3, parent); parent.Triangles.Add(new_tri); Triangles.Add(new_tri); } }
public static Mesh ImportFromCollada(mesh mesh, string vertexFormat, bool rebuildNormals = false, bool rebuildTangents = false) { var collada = new ColladaMesh(); collada.ImportFromCollada(mesh, vertexFormat, rebuildNormals, rebuildTangents); var m = new Mesh(); m.VertexFormat = VertexFormatRegistry.Resolve(vertexFormat); m.Name = "Unnamed"; m.PrimaryVertexData = new VertexData(); var components = new List <GrannyString>(); components.Add(new GrannyString("Position")); var vertexDesc = Vertex.Description(m.VertexFormat); if (vertexDesc.BoneWeights) { components.Add(new GrannyString("BoneWeights")); components.Add(new GrannyString("BoneIndices")); } components.Add(new GrannyString("Normal")); components.Add(new GrannyString("Tangent")); components.Add(new GrannyString("Binormal")); components.Add(new GrannyString("MaxChannel_1")); m.PrimaryVertexData.VertexComponentNames = components; m.PrimaryVertexData.Vertices = collada.ConsolidatedVertices; m.PrimaryTopology = new TriTopology(); m.PrimaryTopology.Indices = collada.ConsolidatedIndices; m.PrimaryTopology.Groups = new List <TriTopologyGroup>(); var triGroup = new TriTopologyGroup(); triGroup.MaterialIndex = 0; triGroup.TriFirst = 0; triGroup.TriCount = collada.TriangleCount; m.PrimaryTopology.Groups.Add(triGroup); m.MaterialBindings = new List <MaterialBinding>(); m.MaterialBindings.Add(new MaterialBinding()); // m.BoneBindings; - TODO m.OriginalToConsolidatedVertexIndexMap = collada.OriginalToConsolidatedVertexIndexMap; Utils.Info(String.Format("Imported {0} mesh ({1} tri groups, {2} tris)", (vertexDesc.BoneWeights ? "skinned" : "rigid"), m.PrimaryTopology.Groups.Count, collada.TriangleCount)); return(m); }
private static STGenericMesh LoadMeshData(ColladaScene scene, Node node, geometry geom, library_materials materials, controller controller = null) { mesh daeMesh = geom.Item as mesh; STGenericMesh mesh = new STGenericMesh(); mesh.Vertices = new List <STVertex>(); mesh.Name = geom.name; var boneWeights = ParseWeightController(controller, scene); foreach (var item in daeMesh.Items) { //Poly lists can control specific amounts of indices for primitive types like quads if (item is polylist) { var poly = item as polylist; ConvertPolygon(scene, mesh, daeMesh, poly.input, boneWeights, materials, poly.material, poly.p, (int)poly.count, poly.vcount); } else if (item is triangles) { var triangle = item as triangles; ConvertPolygon(scene, mesh, daeMesh, triangle.input, boneWeights, materials, triangle.material, triangle.p, (int)triangle.count); } } foreach (var vertex in mesh.Vertices) { if (scene.Settings.FlipUVsVertical) { for (int i = 0; i < vertex.TexCoords.Length; i++) { vertex.TexCoords[i] = new Vector2(vertex.TexCoords[i].X, 1 - vertex.TexCoords[i].Y); } } vertex.Position = Vector3.TransformPosition(vertex.Position, node.Transform); vertex.Position = Vector3.TransformPosition(vertex.Position, Matrix4.CreateScale(0.01f)); //vertex.Normal = Vector3.TransformNormal(vertex.Normal, node.Transform); } return(mesh); }
private void OnValidate() { if (transform.position != Vector3.zero) { transform.position = Vector3.zero; } int i = 0; while (transform.childCount < 6) { GameObject face = new GameObject("Face" + transform.childCount.ToString(), typeof(MeshFilter), typeof(MeshRenderer), typeof(mesh)); mesh mesh = face.GetComponent <mesh>(); mesh.mat = this.mat; mesh.precision = this.precision; // MF = face.GetComponent<MeshFilter>(); face.transform.SetParent(this.transform); var c = facePos[i]; face.transform.position = transform.position + new Vector3(c.x, c.y, c.z); face.transform.rotation = Quaternion.Euler(c.w * (Convert.ToInt16(i > 3)), 0, c.w * (Convert.ToInt16(i <= 3))); mesh.initialPos = face.transform.position; mesh.initialRotation = face.transform.rotation; i++; } foreach (Transform face in transform) { mesh mesh = face.GetComponent <mesh>(); mesh.precision = this.precision; mesh.radius = this.radius; mesh.mat = this.mat; mesh.Create(); if (spherize) { mesh.sphere = true; mesh.sphereCenter = this.transform; mesh.spherize(); } else { mesh.sphere = false; } } }
void workTheStack(string opElement, double[] vertices, int[] indices, int[] vertexCounts, int[] indexCounts, int[] vertexShifts, int[] indexShifts, Stack <mesh> CSGStack) { if (IsOperand(opElement)) { int meshIndex; // vertexCount, indexCount, vertexshift, indexShift; int.TryParse(opElement, out meshIndex); // return error message here mesh Operand = new mesh(); Operand.V = new double[vertexCounts[meshIndex] * 3]; Operand.I = new int[indexCounts[meshIndex]]; Array.Copy(vertices, vertexShifts[meshIndex] * 3, Operand.V, 0, vertexCounts[meshIndex] * 3); Array.Copy(indices, indexShifts[meshIndex], Operand.I, 0, indexCounts[meshIndex]); CSGStack.Push(Operand); } else //if operator { mesh B = CSGStack.Pop(); mesh A = CSGStack.Pop(); mesh C = new mesh(); // C.V = new double[]; // C.I = new int[6]; double[] V; // int[] binNew = new int[2]; int[] binSizes = new int[4]; binSizes[0] = A.V.Length / 3; binSizes[1] = A.I.Length; binSizes[2] = B.V.Length / 3; binSizes[3] = B.I.Length; try { // meshBoolean(opElement, A.V, A.I, B.V, B.I, binSizes); // binTest[0] = binNew[0]; C.V = new double[binNew[0]]; C.I = new int[binNew[1]]; getValues(C.V, C.I); CSGStack.Push(C); } catch (Exception ex) { } } }
public mesh Export() { Sources = new List <source>(); Inputs = new List <InputLocal>(); InputOffsets = new List <InputLocalOffset>(); LastInputOffset = 0; var vertexData = ExportedMesh.PrimaryVertexData; if (vertexData.Vertices != null && vertexData.Vertices.Count > 0) { var vertex = vertexData.Vertices[0]; DetermineInputsFromVertex(vertex); } else { var componentNames = ExportedMesh.VertexComponentNames(); DetermineInputsFromComponentNames(componentNames); } // TODO: model transform/inverse transform? var triangles = ExportedMesh.PrimaryTopology.MakeColladaTriangles( InputOffsets.ToArray(), vertexData.Deduplicator.Vertices.DeduplicationMap, vertexData.Deduplicator.Normals.DeduplicationMap, vertexData.Deduplicator.UVs.Select(uv => uv.DeduplicationMap).ToList(), vertexData.Deduplicator.Colors.Select(color => color.DeduplicationMap).ToList() ); var colladaMesh = new mesh(); colladaMesh.vertices = new vertices(); colladaMesh.vertices.id = ExportedMesh.Name + "-vertices"; colladaMesh.vertices.input = Inputs.ToArray(); colladaMesh.source = Sources.ToArray(); colladaMesh.Items = new object[] { triangles }; return(colladaMesh); }
private DivinityModelFlag FindDivModelType(mesh mesh) { DivinityModelFlag flags = 0; var technique = FindExporterExtraData(mesh.extra); if (technique != null) { if (technique.Any != null) { foreach (var setting in technique.Any) { if (setting.LocalName == "DivModelType") { switch (setting.InnerText.Trim()) { // Compatibility flag, not used anymore case "Normal": break; case "Cloth": flags |= DivinityModelFlag.Cloth; break; case "Rigid": flags |= DivinityModelFlag.Rigid; break; case "MeshProxy": flags |= DivinityModelFlag.MeshProxy | DivinityModelFlag.HasProxyGeometry; break; default: Utils.Warn($"Unrecognized model type in <DivModelType> tag: {setting.Value}"); break; } } } } } return(flags); }
protected mesh CreateComplexCaseMesh(BoxProperties caseProperties) { // build box Box box = new Box(0, caseProperties); // build list of vertex double ct = 5.0; Vector3D[] vertices = new Vector3D[16]; // 1st layer vertices[0] = new Vector3D(ct, ct, 0.0); vertices[1] = new Vector3D(box.Length - ct, ct, 0.0); vertices[2] = new Vector3D(box.Length - ct, box.Width - ct, 0.0); vertices[3] = new Vector3D(ct, box.Width - ct, 0.0); // 2nd layer (8) vertices[4] = new Vector3D(0.0, 0.0, ct); vertices[5] = new Vector3D(box.Length, 0.0, ct); vertices[6] = new Vector3D(box.Length, box.Width, ct); vertices[7] = new Vector3D(0.0, box.Width, ct); // 3rd later (8) vertices[8] = new Vector3D(0.0, 0.0, box.Height - ct); vertices[9] = new Vector3D(box.Length, 0.0, box.Height - ct); vertices[10] = new Vector3D(box.Length, box.Width, box.Height - ct); vertices[11] = new Vector3D(0.0, box.Width, box.Height - ct); // 4th layer vertices[12] = new Vector3D(ct, ct, box.Height); vertices[13] = new Vector3D(box.Length - ct, ct, box.Height); vertices[14] = new Vector3D(box.Length - ct, box.Width - ct, box.Height); vertices[15] = new Vector3D(ct, box.Width - ct, box.Height); // build list of loops Loop[] loops = new Loop[14]; mesh caseMesh = new mesh(); return(caseMesh); }
private Mesh ImportMesh(geometry geom, mesh mesh, string vertexFormat) { var collada = new ColladaMesh(); bool isSkinned = SkinnedMeshes.Contains(geom.id); collada.ImportFromCollada(mesh, vertexFormat, isSkinned, Options); var m = new Mesh(); m.VertexFormat = collada.InternalVertexType; m.Name = "Unnamed"; m.PrimaryVertexData = new VertexData(); var components = new List <GrannyString>(); components.Add(new GrannyString("Position")); var vertexDesc = Vertex.Description(m.VertexFormat); if (vertexDesc.BoneWeights) { components.Add(new GrannyString("BoneWeights")); components.Add(new GrannyString("BoneIndices")); } if (vertexDesc.Normal) { components.Add(new GrannyString("Normal")); } if (vertexDesc.Tangent) { components.Add(new GrannyString("Tangent")); } if (vertexDesc.Binormal) { components.Add(new GrannyString("Binormal")); } for (int i = 0; i < vertexDesc.DiffuseColors; i++) { components.Add(new GrannyString("DiffuseColor" + i.ToString())); } for (int i = 0; i < vertexDesc.TextureCoordinates; i++) { components.Add(new GrannyString("TextureCoordinate" + i.ToString())); } m.PrimaryVertexData.VertexComponentNames = components; m.PrimaryVertexData.Vertices = collada.ConsolidatedVertices; m.PrimaryTopology = new TriTopology(); m.PrimaryTopology.Indices = collada.ConsolidatedIndices; m.PrimaryTopology.Groups = new List <TriTopologyGroup>(); var triGroup = new TriTopologyGroup(); triGroup.MaterialIndex = 0; triGroup.TriFirst = 0; triGroup.TriCount = collada.TriangleCount; m.PrimaryTopology.Groups.Add(triGroup); m.MaterialBindings = new List <MaterialBinding>(); m.MaterialBindings.Add(new MaterialBinding()); // m.BoneBindings; - TODO m.OriginalToConsolidatedVertexIndexMap = collada.OriginalToConsolidatedVertexIndexMap; Utils.Info(String.Format("Imported {0} mesh ({1} tri groups, {2} tris)", (vertexDesc.BoneWeights ? "skinned" : "rigid"), m.PrimaryTopology.Groups.Count, collada.TriangleCount)); return(m); }
public void Export(RootEntity[] entities, string selectedPath) { for (int i = 0; i < entities.Length; i++) { var entity = entities[i]; var modelCount = entity.ChildEntities.Length; var geometries = new library_geometries { geometry = new geometry[modelCount] }; var visualSceneNodes = new node[modelCount]; const string visualSceneName = "visual-scene"; var visualScenes = new library_visual_scenes { visual_scene = new[] { new visual_scene { id = visualSceneName, name = visualSceneName, node = visualSceneNodes } } }; for (int j = 0; j < modelCount; j++) { var model = (ModelEntity)entity.ChildEntities[j]; var modelName = string.Format("model-{0}-lib", j); var materialName = string.Format("{0}-material", modelName); var triangleCount = model.Triangles.Count(); var elementGroupCount = triangleCount * 3; var elementCount = elementGroupCount * 3; var acessorParams = new[] { new param { name = "X", type = "float" }, new param { name = "Y", type = "float" }, new param { name = "Z", type = "float" } }; #region Position var positionArrayName = string.Format("{0}-positions-array", modelName); var positionAccessor = new accessor { count = (ulong)elementGroupCount, offset = 0, source = string.Format("#{0}", positionArrayName), stride = 3, param = acessorParams }; var positionTechnique = new sourceTechnique_common { accessor = positionAccessor }; var positionArrayValues = new double[elementCount]; var positionArray = new float_array { id = positionArrayName, count = (ulong)elementCount, Values = positionArrayValues }; var positionName = string.Format("{0}-positions", modelName); var positionSource = new source { id = positionName, name = "position", Item = positionArray, technique_common = positionTechnique }; #endregion #region Normal var normalArrayName = string.Format("{0}-normals-array", modelName); var normalAccessor = new accessor { count = (ulong)elementGroupCount, offset = 0, source = string.Format("#{0}", normalArrayName), stride = 3, param = acessorParams }; var normalTechinique = new sourceTechnique_common { accessor = normalAccessor }; var normalArrayValues = new double[elementCount]; var normalArray = new float_array { id = normalArrayName, count = (ulong)elementCount, Values = normalArrayValues }; var normalName = string.Format("{0}-normals", modelName); var normalSource = new source { id = normalName, name = "normal", Item = normalArray, technique_common = normalTechinique }; #endregion #region Processing var triangleIndices = new StringBuilder(); for (int l = 0; l < model.Triangles.Length; l++) { var triangle = model.Triangles[l]; for (var k = 0; k < 3; k++) { var elementIndex = l * 3 + k; var vertex = triangle.Vertices[k]; var normal = triangle.Normals[k]; var color = triangle.Colors[k]; var uv = triangle.Uv[k]; positionArrayValues[elementIndex] = vertex.X; positionArrayValues[elementIndex + 1] = vertex.Y; positionArrayValues[elementIndex + 2] = vertex.Z; normalArrayValues[elementIndex] = normal.X; normalArrayValues[elementIndex + 1] = normal.Y; normalArrayValues[elementIndex + 2] = normal.Z; triangleIndices.Append(elementIndex); triangleIndices.Append(" "); } } #endregion #region Vertices var verticesName = string.Format("{0}-vertices", modelName); var triangles = new triangles { count = (ulong)triangleCount, material = materialName, input = new[] { new InputLocalOffset { offset = 0, semantic = "VERTEX", source = string.Format("#{0}", verticesName) }//, //new InputLocalOffset //{ // offset = 1, // semantic = "NORMAL", // source = string.Format("#{0}", normalName) //} }, p = triangleIndices.ToString() }; #endregion #region Mesh var mesh = new mesh { source = new[] { positionSource, normalSource }, vertices = new vertices { id = verticesName, input = new[] { new InputLocal { semantic = "POSITION", source = string.Format("#{0}", positionName) } } }, Items = new object[] { triangles } }; #endregion #region Geometry var geometryName = string.Format("{0}-geometry", modelName); var geometry = new geometry { id = geometryName, name = geometryName, Item = mesh }; geometries.geometry[j] = geometry; #endregion #region Visual Node var visualSceneNodeName = string.Format("{0}-node", modelName); visualSceneNodes[j] = new node { name = visualSceneNodeName, id = visualSceneNodeName, instance_geometry = new[] { new instance_geometry { url = string.Format("#{0}", geometryName) } } }; #endregion } var collada = new COLLADA { Items = new Object[] { geometries, visualScenes }, scene = new COLLADAScene { instance_visual_scene = new InstanceWithExtra { url = string.Format("#{0}", visualSceneName) } } }; var fileName = string.Format("{0}/dae{1}.dae", selectedPath, i); collada.Save(fileName); } }
protected mesh CreatePalletMesh(PalletProperties palletProperties) { // build pallet object Pallet pallet = new Pallet(palletProperties); // build list of boxes List <Box> listBoxes = pallet.BuildListOfBoxes(); // build list of vertices / normals / UVs ulong vertexCount = 0, normalCount = 0, uvCount = 0, triangleCount = 0, boxCount = 0; string triangle_string = string.Empty; List <double> doubleArrayPosition = new List <double>(), doubleArrayNormal = new List <double>(), doubleArrayUV = new List <double>(); foreach (Box box in listBoxes) { foreach (Vector3D p in box.Points) { doubleArrayPosition.Add(p.X); doubleArrayPosition.Add(p.Y); doubleArrayPosition.Add(p.Z); ++vertexCount; } foreach (Vector3D n in box.Normals) { doubleArrayNormal.Add(n.X); doubleArrayNormal.Add(n.Y); doubleArrayNormal.Add(n.Z); ++normalCount; } foreach (Vector2D uv in box.UVs) { doubleArrayUV.Add(uv.X); doubleArrayUV.Add(uv.Y); ++uvCount; } foreach (TriangleIndices tr in box.Triangles) { triangle_string += tr.ConvertToString(boxCount); ++triangleCount; } ++boxCount; } mesh palletMesh = new mesh(); // position source source palletPositionSource = new source() { id = "pallet_position", name = "pallet_position" }; float_array farrayPosition = new float_array { id = "pallet_position_float_array", count = (ulong)doubleArrayPosition.Count, Values = doubleArrayPosition.ToArray() }; palletPositionSource.technique_common = new sourceTechnique_common() { accessor = new accessor() { stride = 3, count = vertexCount, source = "#pallet_position_float_array", param = new param[] { new param() { name = "X", type = "float" }, new param() { name = "Y", type = "float" }, new param() { name = "Z", type = "float" } } } }; palletPositionSource.Item = farrayPosition; // normal source source palletPositionNormal = new source() { id = "pallet_normal", name = "pallet_normal" }; float_array farrayNormal = new float_array { id = "pallet_normal_float_array", count = (ulong)doubleArrayNormal.Count, Values = doubleArrayNormal.ToArray() }; palletPositionNormal.technique_common = new sourceTechnique_common() { accessor = new accessor() { stride = 3, count = normalCount, source = "#pallet_normal_float_array", param = new param[] { new param() { name = "X", type = "float" }, new param() { name = "Y", type = "float" }, new param() { name = "Z", type = "float" } } } }; palletPositionNormal.Item = farrayNormal; // uv source source palletPositionUV = new source() { id = "pallet_UV", name = "pallet_UV" }; float_array farrayUV = new float_array { id = "pallet_UV_float_array", count = (ulong)doubleArrayUV.Count, Values = doubleArrayUV.ToArray() }; palletPositionUV.technique_common = new sourceTechnique_common() { accessor = new accessor() { stride = 2, count = vertexCount, source = "#pallet_UV_float_array", param = new param[] { new param() { name = "S", type = "float" }, new param() { name = "T", type = "float" } } } }; palletPositionUV.Item = farrayUV; // insert sources palletMesh.source = new source[] { palletPositionSource, palletPositionNormal, palletPositionUV }; // vertices InputLocal verticesInput = new InputLocal() { semantic = "POSITION", source = "#pallet_position" }; palletMesh.vertices = new vertices() { id = "pallet_vertex", input = new InputLocal[] { verticesInput } }; triangles trianglesPallet = new triangles() { material = "materialPallet", count = triangleCount }; trianglesPallet.input = new InputLocalOffset[] { new InputLocalOffset() { semantic = "VERTEX", source = "#pallet_vertex", offset = 0 } , new InputLocalOffset() { semantic = "NORMAL", source = "#pallet_normal", offset = 1 } , new InputLocalOffset() { semantic = "TEXCOORD", source = "#pallet_UV", offset = 2, set = 0, setSpecified = true } }; trianglesPallet.p = triangle_string; palletMesh.Items = new object[] { trianglesPallet }; return(palletMesh); }
protected mesh CreateCaseMesh(BoxProperties caseProperties) { // build box Box box = new Box(0, caseProperties); // build list of vertices / normals / UVs ulong vertexCount = 0, normalCount = 0, uvCount = 0; List <double> doubleArrayPosition = new List <double>(), doubleArrayNormal = new List <double>(), doubleArrayUV = new List <double>(); foreach (Vector3D p in box.PointsSmallOffset) { doubleArrayPosition.Add(p.X); doubleArrayPosition.Add(p.Y); doubleArrayPosition.Add(p.Z); ++vertexCount; } foreach (Vector3D n in box.Normals) { doubleArrayNormal.Add(n.X); doubleArrayNormal.Add(n.Y); doubleArrayNormal.Add(n.Z); ++normalCount; } foreach (Vector2D uv in box.UVs) { doubleArrayUV.Add(uv.X); doubleArrayUV.Add(uv.Y); ++uvCount; } mesh caseMesh = new mesh(); // position source source casePositionSource = new source() { id = "case_position", name = "case_position" }; float_array farrayPosition = new float_array { id = "case_position_float_array", count = (ulong)doubleArrayPosition.Count, Values = doubleArrayPosition.ToArray() }; casePositionSource.technique_common = new sourceTechnique_common() { accessor = new accessor() { stride = 3, count = vertexCount, source = "#case_position_float_array", param = new param[] { new param() { name = "X", type = "float" }, new param() { name = "Y", type = "float" }, new param() { name = "Z", type = "float" } } } }; casePositionSource.Item = farrayPosition; // normal source source casePositionNormal = new source() { id = "case_normal", name = "case_normal" }; float_array farrayNormal = new float_array { id = "case_normal_float_array", count = (ulong)doubleArrayNormal.Count, Values = doubleArrayNormal.ToArray() }; casePositionNormal.technique_common = new sourceTechnique_common() { accessor = new accessor() { stride = 3, count = normalCount, source = "#case_normal_float_array", param = new param[] { new param() { name = "X", type = "float" }, new param() { name = "Y", type = "float" }, new param() { name = "Z", type = "float" } } } }; casePositionNormal.Item = farrayNormal; // uv source source casePositionUV = new source() { id = "case_UV", name = "pallet_UV" }; float_array farrayUV = new float_array { id = "case_UV_float_array", count = (ulong)doubleArrayUV.Count, Values = doubleArrayUV.ToArray() }; casePositionUV.technique_common = new sourceTechnique_common() { accessor = new accessor() { stride = 2, count = vertexCount, source = "#case_UV_float_array", param = new param[] { new param() { name = "S", type = "float" }, new param() { name = "T", type = "float" } } } }; casePositionUV.Item = farrayUV; // insert sources caseMesh.source = new source[] { casePositionSource, casePositionNormal, casePositionUV }; // vertices InputLocal verticesInput = new InputLocal() { semantic = "POSITION", source = "#case_position" }; caseMesh.vertices = new vertices() { id = "case_vertex", input = new InputLocal[] { verticesInput } }; List <object> trianglesList = new List <object>(); // build list of triangles foreach (HalfAxis.HAxis axis in HalfAxis.All) { triangles trianglesCase = new triangles() { material = string.Format("materialCase{0}", (uint)axis), count = 2 }; trianglesCase.input = new InputLocalOffset[] { new InputLocalOffset() { semantic = "VERTEX", source = "#case_vertex", offset = 0 } , new InputLocalOffset() { semantic = "NORMAL", source = "#case_normal", offset = 1 } , new InputLocalOffset() { semantic = "TEXCOORD", source = "#case_UV", offset = 2, set = 0, setSpecified = true } }; string triangle_string = string.Empty; foreach (TriangleIndices tr in box.TrianglesByFace(axis)) { triangle_string += tr.ConvertToString(0); } trianglesCase.p = triangle_string; trianglesList.Add(trianglesCase); } // build list of lines lines linesCase = new lines() { material = "materialCaseLines", count = 12, input = new InputLocalOffset[] { new InputLocalOffset() { semantic = "VERTEX", source = "#case_vertex", offset = 0 } }, p = "0 1 1 2 2 3 3 0 4 5 5 6 6 7 7 4 0 4 1 5 2 6 3 7" }; trianglesList.Add(linesCase); caseMesh.Items = trianglesList.ToArray(); return(caseMesh); }
private void initializeObjects() { meshCube = new mesh(); meshCube.loadFromObjFileAt("spaceShip.obj", 0, 0, 0); meshCube.loadFromObjFileAt("spaceShip.obj", 0, 2, 15); }
static List <CELLMARK> cellmark_List = new List <CELLMARK>(); // для текущей сцены static void Main() { var filesName = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.cellgrup", SearchOption.AllDirectories); System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US"); List <Model> Models = new List <Model>(); // список мешей на сцене foreach (var file in filesName) { byte[] array1d = File.ReadAllBytes(file); int ci = 0; // счётчик вхождений //88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888 using (var br = new BinaryReader(File.Open(file, FileMode.Open))) { for (int i = 0; i < array1d.Length; i++) // проходим по всем байтам файла *.cellgrup { if (array1d[i + 0] == 0x69 && array1d[i + 1] == 0x00 && array1d[i + 2] == 0x00 && array1d[i + 3] == 0x00 && // i*** array1d[i + 4] == 0x64 && array1d[i + 5] == 0x65 && array1d[i + 6] == 0x66 && array1d[i + 7] == 0x61 && // defa array1d[i + 8] == 0x75 && array1d[i + 9] == 0x6C && array1d[i + 10] == 0x74 && array1d[i + 11] == 0x00) // ult* { br.BaseStream.Position = i + 12; // отступаем от "вхождения" на i***default* байт int BlockSize = br.ReadInt32(); // размер блока br.ReadInt32(); // пропускаем пустые байты [00 00 00 00] int type = br.ReadInt32(); // "тип" модели if (type == 1819045731) { ci++; // coll[modc] } if (type == 1634493549) { ci++; // mdla[ttr*] } if (type == 6581618) // только для rmd*[****] { br.BaseStream.Position = i + 4; // "возвращаемся", чтобы скопировать модель Model mesh = new Model(); // создаём модель mesh.BaseStreamPosition = br.BaseStream.Position; mesh.type = type; mesh.index = ci++; // присваиваем и увеличиваем индекс mesh.content = br.ReadBytes(BlockSize).ToList(); Models.Add(mesh); // добавляем её в список моделей на "сцене" } i = i + BlockSize; // ускоряем поиск? } // 63 65 6C 6C 69 6E 73 74 (места моделей) if (array1d[i + 0] == 0x63 && array1d[i + 1] == 0x65 && array1d[i + 2] == 0x6C && array1d[i + 3] == 0x6C && // cell array1d[i + 4] == 0x69 && array1d[i + 5] == 0x6E && array1d[i + 6] == 0x73 && array1d[i + 7] == 0x74) // inst { br.BaseStream.Position = i + 16; int count = br.ReadInt32(); // кол-во координат для расстановки моделей for (int j = 0; j < count; j++) { CELLINST cellinst = new CELLINST(br); cellinst_List.Add(cellinst); } } // 63 65 6C 6C 6D 61 72 6B cellmark if (array1d[i + 0] == 0x63 && array1d[i + 1] == 0x65 && array1d[i + 2] == 0x6C && array1d[i + 3] == 0x6C && // cell array1d[i + 4] == 0x6D && array1d[i + 5] == 0x61 && array1d[i + 6] == 0x72 && array1d[i + 7] == 0x6B) // mark { br.BaseStream.Position = i + 16; int count = br.ReadInt32(); // кол-во координат для расстановки моделей for (int j = 0; j < count; j++) { CELLMARK cellmark = new CELLMARK(br); cellmark_List.Add(cellmark); } } } //88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888 foreach (var mesh in Models) { for (int ji = 0; ji < mesh.content.Count; ji++) { // ИЩЕМ ВЕРШИНЫ // v // если нашли строку "position" = 00 00 00 00 70 6F 73 69 74 69 6F 6E if (mesh.content[ji + 0] == 0x70 && mesh.content[ji + 1] == 0x6F && mesh.content[ji + 2] == 0x73 && mesh.content[ji + 3] == 0x69 && // 70 6F 73 69 mesh.content[ji + 4] == 0x74 && mesh.content[ji + 5] == 0x69 && mesh.content[ji + 6] == 0x6F && mesh.content[ji + 7] == 0x6E) // 74 69 6F 6E { br.BaseStream.Position = mesh.BaseStreamPosition + ji + 16; // +20, если отступаем OOOO_position int count = br.ReadInt32(); for (int j = 0; j < count; j++) { mesh.positionList.Add(new Vector3(br)); } } ///////////// ИЩЕМ Vn (нормали) if (mesh.content[ji + 0] == 0x6E && mesh.content[ji + 1] == 0x6F && mesh.content[ji + 2] == 0x72 && mesh.content[ji + 3] == 0x6D && // 6E 6F 72 6D mesh.content[ji + 4] == 0x61 && mesh.content[ji + 5] == 0x6C && mesh.content[ji + 6] == 0x73 && mesh.content[ji + 7] == 0x00) // 61 6C 73 00 { br.BaseStream.Position = mesh.BaseStreamPosition + ji + 16; int count = br.ReadInt32(); for (int j = 0; j < count; j++) { mesh.normalsList.Add(new Vector3(br)); } } ///////////// ИЩЕМ ГРАНИ FACES // 70 72 69 6D // 73 ( 00 00 00 ) if (mesh.content[ji + 0] == 0x70 && mesh.content[ji + 1] == 0x72 && mesh.content[ji + 2] == 0x69 && mesh.content[ji + 3] == 0x6D) // 70 72 69 6D 73 { br.BaseStream.Position = mesh.BaseStreamPosition + ji + 16; int primsCount = br.ReadInt32(); for (int j = 0; j < primsCount; j++) { int faceNumber = br.ReadInt32(); int faceCount = br.ReadInt32(); int faceSize = br.ReadInt32(); List <TRI> face = new List <TRI>(); for (int f = 0; f < faceCount; f++) { face.Add(new TRI(br, faceNumber)); } mesh.subMeshFaces.Add(face); for (int jj = 0; jj < 10; jj++) { br.ReadInt32(); // непонятные данные, мб для наложения текстур } if ((faceCount % 2) != 0) { br.ReadUInt16(); // для "выравнивания" читается FF FF } } } ///////////// ИЩЕМ uvs index , индексы текстурных координат // строку "textures" = // (00 00 FF FF) 74 65 78 74 75 72 65 73 // if ( mesh.content[ji+0] == 0x00 && mesh.content[ji+1] == 0x00 && mesh.content[ji+2] == 0x00 && mesh.content[ji+3] == 0x00 && // это необходимо ? if (mesh.content[ji + 0] == 0x74 && mesh.content[ji + 1] == 0x65 && mesh.content[ji + 2] == 0x78 && mesh.content[ji + 3] == 0x74 && // если да mesh.content[ji + 4] == 0x75 && mesh.content[ji + 5] == 0x72 && mesh.content[ji + 6] == 0x65 && mesh.content[ji + 7] == 0x73) // то изменить индексы { br.BaseStream.Position = mesh.BaseStreamPosition + ji + 16; // или +20 в big файле int count = br.ReadInt32(); for (int j = 0; j < count; j++) { mesh.texturesList.Add(br.ReadUInt16()); } } ///////////// ТЕКСТУРНЫЕ КООРДИНАТЫ // vt // uvs. // 75 76 73 00 00 00 00 00 // может попастся два набора, поэтому пока что сохраняем смещение, а затем читаем что надо if (mesh.content[ji + 0] == 0x75 && mesh.content[ji + 1] == 0x76 && mesh.content[ji + 2] == 0x73 && mesh.content[ji + 3] == 0x00) // 75 76 73 00 { uvs_offset_int_list.Add(ji); } /////////////// /* * // mdlattr* * * if ( mesh.content[ji+0] == 0x6D && mesh.content[ji+1] == 0x64 && mesh.content[ji+2] == 0x6C && mesh.content[ji+3] == 0x61 && * mesh.content[ji+4] == 0x74 && mesh.content[ji+5] == 0x74 && mesh.content[ji+6] == 0x72 && mesh.content[ji+7] == 0x00) * { * br.BaseStream.Position = mesh.BaseStreamPosition + ji + 8; * int BlockSize = br.ReadInt32(); br.ReadInt32(); // 00 00 00 00 * * br.ReadInt32(); // 00 00 00 00 * br.ReadInt32(); // 00 00 00 00 * * int defaultBlockSize = br.ReadInt32(); * * br.ReadInt32(); * br.ReadInt32(); * } */ ///////////// mtlctrl* // 6D 74 6C 63 74 72 6C 00 if (mesh.content[ji + 0] == 0x6D && mesh.content[ji + 1] == 0x74 && mesh.content[ji + 2] == 0x6C && mesh.content[ji + 3] == 0x63 && // 6D 74 6C 63 mesh.content[ji + 4] == 0x74 && mesh.content[ji + 5] == 0x72 && mesh.content[ji + 6] == 0x6C && mesh.content[ji + 7] == 0x00) // 74 72 6C 00 { br.BaseStream.Position = mesh.BaseStreamPosition + ji + 16; int count = br.ReadInt32(); for (int j = 0; j < count; j++) { Mtlctrl mtlctrl = new Mtlctrl(br); mesh.mtlctrlList.Add(mtlctrl); } } ///////////// mlyrcolr ??? привильно ли я добавляю в список? по "сомнению" надо выделить три "строки" в один объект if (mesh.content[ji + 0] == 0x6D && mesh.content[ji + 1] == 0x6C && mesh.content[ji + 2] == 0x79 && mesh.content[ji + 3] == 0x72 && // 6D 6C 79 72 mesh.content[ji + 4] == 0x63 && mesh.content[ji + 5] == 0x6F && mesh.content[ji + 6] == 0x6C && mesh.content[ji + 7] == 0x72) // 63 6F 6C 72 { br.BaseStream.Position = mesh.BaseStreamPosition + ji + 20; int count = br.ReadInt32(); for (int j = 0; j < count; j++) { for (int jj = 0; jj < 3; jj++) { Mlyrcolr mlyrcolr = new Mlyrcolr(br); mesh.mlyrcolrList.Add(mlyrcolr); } } } ///////////// mlyrctrl +++ if (mesh.content[ji + 0] == 0x6D && mesh.content[ji + 1] == 0x6C && mesh.content[ji + 2] == 0x79 && mesh.content[ji + 3] == 0x72 && // 6D 6C 79 72 mesh.content[ji + 4] == 0x63 && mesh.content[ji + 5] == 0x74 && mesh.content[ji + 6] == 0x72 && mesh.content[ji + 7] == 0x6C) // 63 74 72 6C { br.BaseStream.Position = mesh.BaseStreamPosition + ji + 16; int flag = br.ReadInt32(); // 0 или 1 int count = br.ReadInt32(); for (int j = 0; j < count; j++) { Mlyrctrl m = new Mlyrctrl(br); mesh.mlyrctrlList.Add(m); } } ///////////// texture* +++ if (mesh.content[ji + 0] == 0x74 && mesh.content[ji + 1] == 0x65 && mesh.content[ji + 2] == 0x78 && mesh.content[ji + 3] == 0x74 && // 74 65 78 74 mesh.content[ji + 4] == 0x75 && mesh.content[ji + 5] == 0x72 && mesh.content[ji + 6] == 0x65 && mesh.content[ji + 7] == 0x00) // 75 72 65 00 { br.BaseStream.Position = mesh.BaseStreamPosition + ji + 20; // br.BaseStream.Position = mesh.BaseStreamPosition + ji + 20; int count = br.ReadInt32(); for (int j = 0; j < count; j++) { Texture thz = new Texture(br); mesh.texture_List.Add(thz); } } ///////////// vtxweigh +++ if (mesh.content[ji + 0] == 0x76 && mesh.content[ji + 1] == 0x74 && mesh.content[ji + 2] == 0x78 && mesh.content[ji + 3] == 0x77 && // 76 74 78 77 mesh.content[ji + 4] == 0x65 && mesh.content[ji + 5] == 0x69 && mesh.content[ji + 6] == 0x67 && mesh.content[ji + 7] == 0x68) // 65 69 67 68 { br.BaseStream.Position = mesh.BaseStreamPosition + ji + 16; int count = br.ReadInt32(); for (int ii = 0; ii < count; ii++) { mesh.vtxweighList.Add(br.ReadSingle()); } } ///////////// jointidx +++ if (mesh.content[ji + 0] == 0x6A && mesh.content[ji + 1] == 0x6F && mesh.content[ji + 2] == 0x69 && mesh.content[ji + 3] == 0x6E && // 6A 6F 69 6E // join mesh.content[ji + 4] == 0x74 && mesh.content[ji + 5] == 0x69 && mesh.content[ji + 6] == 0x64 && mesh.content[ji + 7] == 0x78) // 74 69 64 78 // tidx { br.BaseStream.Position = mesh.BaseStreamPosition + ji + 16; int count = br.ReadInt32(); for (int j = 0; j < count; j++) { mesh.jointidxList.Add(br.ReadUInt16()); } int ffff = 0; if (count % 2 != 0) { ffff = br.ReadUInt16(); } } ///////////// collmodc } // для массива внутри модели //88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888 //88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888 //88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888 if (uvs_offset_int_list.Count > 0) { br.BaseStream.Position = mesh.BaseStreamPosition + uvs_offset_int_list[0] + 8; int BlockSizeU0 = br.ReadInt32(); br.ReadInt32(); int number0 = br.ReadInt32(); // 00 00 00 00 int uvsCount = br.ReadInt32(); for (int uvc = 0; uvc < uvsCount; uvc++) { mesh.uvs0.Add(new Vector2(br)); } mesh.uvsList.Add(mesh.uvs0); } if (uvs_offset_int_list.Count > 1) { br.BaseStream.Position = mesh.BaseStreamPosition + uvs_offset_int_list[1] + 8; int BlockSizeU1 = br.ReadInt32(); br.ReadInt32(); int number1 = br.ReadInt32(); // 01 00 00 00 int uvsCount = br.ReadInt32(); for (int uvc = 0; uvc < uvsCount; uvc++) { mesh.uvs1.Add(new Vector2(br)); } mesh.uvsList.Add(mesh.uvs1); } uvs_offset_int_list.Clear(); // обязательно очищаем для другой модели } // для каждой модели } // binary reader //88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888 //88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888 //88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888 string name = file.Replace(".cellgrup", ""); library_geometries lgeom = new library_geometries() // создаём библиотеку мешей { geometry = new geometry[Models.Count] // в библиотеке геометрии Models.Count мешей }; ///////////////////////////////////////////////////////////////////////////////////////////////// int qqq = 0; // шагаем по списку геометрий в файле foreach (var mesh in Models) // для каждой модели { //----------------------------------------------------------------------------------------------- //{ создаём массив координат для вершин модели float_array xyz_N_array = new float_array() // массив для координат { count = (ulong)mesh.positionList.Count * 3, id = "mesh_" + mesh.index + "_positions_array" }; float_coords = new List <double>(); foreach (var fl in mesh.positionList) { float_coords.Add(fl.x); float_coords.Add(fl.y); float_coords.Add(fl.z); } xyz_N_array.Values = float_coords.ToArray(); //---------------------------------- source pos_source = new source() // источник для координат { Item = xyz_N_array, id = "mesh_" + mesh.index + "_positions", technique_common = new sourceTechnique_common() { accessor = new accessor() { count = (ulong)mesh.positionList.Count, offset = 0L, source = "#" + xyz_N_array.id, stride = 3L, param = new param[] { new param() { name = "X", type = "float" }, new param() { name = "Y", type = "float" }, new param() { name = "Z", type = "float" } } } } }; //} //----------------------------------------------------------------------------------------------- /* * //{ создаём массив координат для нормалей модели * * float_array xyz_Normals = new float_array() * { * count = (ulong)mesh.normalsList.Count * 3; * id = "mesh_" + mesh.index + "_normals_array"; * } * * float_coords = new List<double>(); * * foreach(var fl in mesh.positionList) * { * float_coords.Add(fl.x); * float_coords.Add(fl.y); * float_coords.Add(fl.z); * } * * xyz_Normals.Values = float_coords.ToArray(); * * //---------------------------------- * * source norm_source = new source() * { * Item = xyz_N_array, * id = "mesh_" + mesh.index + "_positions", * * technique_common = new sourceTechnique_common() * { * accessor = new accessor() * { * count = (ulong)mesh.positionList.Count, * offset = 0L, * source = "#" + xyz_N_array.id, * stride = 3L, * * param = new param[] * { * new param() { name = "X", type = "float" }, * new param() { name = "Y", type = "float" }, * new param() { name = "Z", type = "float" } * } * } * } * }; * //} */ //----------------------------------------------------------------------------------------------- vertices v = new vertices() // вершины = часть объекта mesh { id = "mesh_" + mesh.index + "_vertices", input = new InputLocal[] { new InputLocal() // пока что только коорднаты { semantic = "POSITION", source = "#" + pos_source.id } } }; //----------------------------------------------------------------------------------------------- int faceNumber = 0; foreach (var q in mesh.subMeshFaces) { foreach (var qq in q) { faceNumber++; } } triangles tres = new triangles() // треугольники = часть объекта mesh { count = (ulong)faceNumber, input = new InputLocalOffset[] { new InputLocalOffset() // пока что только для координат { semantic = "VERTEX", offset = 0L, source = "#" + v.id } } }; //---------------------------------- StringBuilder all_TRI = new StringBuilder(); foreach (var q in mesh.subMeshFaces) { foreach (var qq in q) { string str = qq.vi0 + " " + qq.vi1 + " " + qq.vi2 + " "; all_TRI.Append(str); } } tres.p = all_TRI.ToString(); //----------------------------------------------------------------------------------------------- mesh m = new mesh() // создаём объект меша { vertices = v, source = new source[1] // пока что только 1 источник для position { pos_source }, Items = new object[1] // для треугольников { tres } }; //----------------------------------------------------------------------------------------------- geometry geom = new geometry() // создаём оболочку для меши { id = "mesh_" + mesh.index, // задаём ей имя mesh_№ Item = m }; lgeom.geometry[qqq++] = geom; } // для каждой модели в файле cellgrup создаём блоки с геометрией //88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888 library_visual_scenes lvs = new library_visual_scenes(); // создаём библиотеку сцен visual_scene vs = new visual_scene() // создаём сцену, вроде всегда одна { id = "MyScene", // обзываем её node = new node[Models.Count] // добавляем узлы для моделей на сцене }; //=============================================================================================== qqq = 0; // шагаем по списку мешей, создаём им ноды, задаём расположение foreach (var mesh in Models) { //---------------------------------- node n = new node() { id = "mesh" + mesh.index, instance_geometry = new instance_geometry[] { new instance_geometry() { url = "#" + lgeom.geometry[qqq].id } } }; //---------------------------------- n.ItemsElementName = new ItemsChoiceType2[5] { ItemsChoiceType2.translate, ItemsChoiceType2.rotate, ItemsChoiceType2.rotate, ItemsChoiceType2.rotate, ItemsChoiceType2.scale }; //---------------------------------- float xx = 0.0f; float yy = 0.0f; float zz = 0.0f; float rx = 0.0f; float ry = 0.0f; float rz = 0.0f; for (int ccc = 0; ccc < cellinst_List.Count; ccc++) { if (mesh.index == cellinst_List[ccc].number) { xx = cellinst_List[ccc].position.x; yy = cellinst_List[ccc].position.y; zz = cellinst_List[ccc].position.z; rx = cellinst_List[ccc].rotation.x; ry = cellinst_List[ccc].rotation.y; rz = cellinst_List[ccc].rotation.z; } } for (int ccc = 0; ccc < cellmark_List.Count; ccc++) { if (mesh.index == cellmark_List[ccc].number1) { xx = cellmark_List[ccc].position.x; yy = cellmark_List[ccc].position.y; zz = cellmark_List[ccc].position.z; rx = cellmark_List[ccc].rotation.x; ry = cellmark_List[ccc].rotation.y; rz = cellmark_List[ccc].rotation.z; } } //---------------------------------- n.Items = new object[5] { new TargetableFloat3() { sid = "location", // translate Values = new double[3] { xx, yy, zz } }, new rotate() { sid = "rotationX", Values = new double[4] { 0, 0, 1, rz *57.5 } }, // Z new rotate() { sid = "rotationY", Values = new double[4] { 0, 1, 0, ry *57.5 } }, // Y почему такой "угол" ? new rotate() { sid = "rotationZ", Values = new double[4] { 1, 0, 0, rx *57.5 } }, // X new TargetableFloat3() { sid = "scale", Values = new double[3] { 1, 1, 1 } } }; //---------------------------------- vs.node[qqq] = n; qqq++; } // для каждой модели в файле cellgrup //----------------------------------------------------------------------------------------------- lvs.visual_scene = new visual_scene[1] // создаём массив для сцен { vs // добавляем visual_scene в library_visual_scenes }; //----------------------------------------------------------------------------------------------- COLLADA collada = new COLLADA() { asset = new asset() { up_axis = UpAxisType.Z_UP }, Items = new object[] // для библиотеки мешей и сцен { lgeom, // присваиваем колладе библиотеку геометрию lvs // в массив Item добавляем библиотеку сцен }, scene = new COLLADAScene() { instance_visual_scene = new InstanceWithExtra() { url = "#" + vs.id } } }; //88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888 collada.Save(name + ".dae"); Models.Clear(); cellinst_List.Clear(); cellmark_List.Clear(); //88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888 } // для каждого cellgrup файла } // void Main()
public void ImportFromCollada(mesh mesh, string vertexFormat, bool rebuildNormals = false, bool rebuildTangents = false) { Mesh = mesh; VertexType = VertexFormatRegistry.Resolve(vertexFormat); ImportSources(); ImportFaces(); ImportVertices(); // TODO: This should be done before deduplication! // TODO: Move this to somewhere else ... ? if (!HasNormals || rebuildNormals) { if (!HasNormals) { Utils.Info(String.Format("Channel 'NORMAL' not found, will rebuild vertex normals after import.")); } computeNormals(); } ImportUVs(); if (UVInputIndices.Count() > 0) { var outVertexIndices = new Dictionary <int[], int>(new VertexIndexComparer()); ConsolidatedIndices = new List <int>(TriangleCount * 3); ConsolidatedVertices = new List <Vertex>(Vertices.Count); OriginalToConsolidatedVertexIndexMap = new Dictionary <int, List <int> >(); for (var vert = 0; vert < TriangleCount * 3; vert++) { var index = new int[Inputs.Length]; for (var i = 0; i < Inputs.Length; i++) { index[i] = Indices[vert * Inputs.Length + i]; } int consolidatedIndex; if (!outVertexIndices.TryGetValue(index, out consolidatedIndex)) { var vertexIndex = index[VertexInputIndex]; consolidatedIndex = ConsolidatedVertices.Count; Vertex vertex = Vertices[vertexIndex].Clone(); for (int uv = 0; uv < UVInputIndices.Count(); uv++) { vertex.SetTextureCoordinates(uv, UVs[uv][index[UVInputIndices[uv]]]); } outVertexIndices.Add(index, consolidatedIndex); ConsolidatedVertices.Add(vertex); List <int> mappedIndices = null; if (!OriginalToConsolidatedVertexIndexMap.TryGetValue(vertexIndex, out mappedIndices)) { mappedIndices = new List <int>(); OriginalToConsolidatedVertexIndexMap.Add(vertexIndex, mappedIndices); } mappedIndices.Add(consolidatedIndex); } ConsolidatedIndices.Add(consolidatedIndex); } Utils.Info(String.Format("Merged {0} vertices into {1} output vertices", Vertices.Count, ConsolidatedVertices.Count)); } else { Utils.Info(String.Format("Mesh has no UV map, vertex consolidation step skipped.")); ConsolidatedVertices = Vertices; ConsolidatedIndices = new List <int>(TriangleCount * 3); for (var vert = 0; vert < TriangleCount * 3; vert++) { ConsolidatedIndices.Add(VertexIndex(vert)); } OriginalToConsolidatedVertexIndexMap = new Dictionary <int, List <int> >(); for (var i = 0; i < Vertices.Count; i++) { OriginalToConsolidatedVertexIndexMap.Add(i, new List <int> { i }); } } if (!HasTangents || rebuildTangents) { if (!HasTangents) { Utils.Info(String.Format("Channel 'TANGENT'/'BINROMAL' not found, will rebuild vertex tangents after import.")); } computeTangents(); } }
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { COLLADA model = new COLLADA(); // init new model.asset = new asset(); model.asset.contributor[1] = new assetContributor(); model.asset.contributor[0] = new assetContributor(); model.asset.unit = new assetUnit(); model.asset.up_axis = new UpAxisType(); model.Items = new object[1]; // asset model.asset.contributor[0].author = "caimagic"; model.asset.contributor[0].authoring_tool = "FBX COLLADA exporter"; model.asset.contributor[0].comments = "hello world"; model.asset.unit.meter = 0.01; model.asset.unit.name = "centimer"; model.asset.up_axis = UpAxisType.Y_UP; // library_geometries library_geometries library_geom = new library_geometries(); library_geom.geometry[1] = new geometry(); library_geom.geometry[0] = new geometry(); geometry geom = new geometry(); mesh geomMesh = new mesh(); geomMesh.source[3] = new source(); geomMesh.source[0] = new source(); geomMesh.source[1] = new source(); geomMesh.source[2] = new source(); float_array position_float_array = new float_array(); float_array normal_float_array = new float_array(); float_array uv_float_array = new float_array(); sourceTechnique_common position_technique_common = new sourceTechnique_common(); sourceTechnique_common normal_technique_common = new sourceTechnique_common(); sourceTechnique_common uv_technique_common = new sourceTechnique_common(); position_float_array.id = "Plane001-POSITION-array"; position_float_array.count = 9; //根据count创建一个数组 position_float_array.Values = new double[position_float_array.count]; position_float_array.Values[0] = -49.719101f; position_float_array.Values[1] = -41.011238f; position_float_array.Values[2] = 0.000000f; position_float_array.Values[3] = 49.719101f; position_float_array.Values[4] = -41.011238f; position_float_array.Values[5] = 0.000000f; position_float_array.Values[6] = -49.719101f; position_float_array.Values[7] = 41.011238f; position_float_array.Values[8] = 0.000000f; position_technique_common.accessor = new accessor(); /* * 创建数组的几种形式 * double[] array = new double[10]; * double[] array = { 0.0, 1.1, 2.2}; * double[] array = new double[5] { 99, 98, 92, 97, 95}; * double[] array = new double[ ] { 99, 98, 92, 97, 95}; * double[] another_array = array;*/ position_technique_common.accessor.param = new param[3]; position_technique_common.accessor.param[0] = new param(); position_technique_common.accessor.param[1] = new param(); position_technique_common.accessor.param[2] = new param(); position_technique_common.accessor.source = "#" + position_float_array.id; position_technique_common.accessor.count = 3; position_technique_common.accessor.stride = 3; position_technique_common.accessor.param[0].name = "X"; position_technique_common.accessor.param[0].type = "float"; position_technique_common.accessor.param[1].name = "Y"; position_technique_common.accessor.param[1].type = "float"; position_technique_common.accessor.param[2].name = "Z"; position_technique_common.accessor.param[2].type = "float"; normal_float_array.id = "Plane001-Normal0-array"; normal_float_array.count = 9; normal_float_array.Values = new double[normal_float_array.count]; normal_float_array.Values[0] = 0.0f; normal_float_array.Values[1] = 0.0f; normal_float_array.Values[2] = 1.0f; normal_float_array.Values[3] = 0.0f; normal_float_array.Values[4] = 0.0f; normal_float_array.Values[5] = 1.0f; normal_float_array.Values[6] = 0.0f; normal_float_array.Values[7] = 0.0f; normal_float_array.Values[8] = 1.0f; normal_technique_common.accessor = new accessor(); normal_technique_common.accessor.param = new param[3]; normal_technique_common.accessor.param[0] = new param(); normal_technique_common.accessor.param[1] = new param(); normal_technique_common.accessor.param[2] = new param(); normal_technique_common.accessor.source = "#" + normal_float_array.id; normal_technique_common.accessor.count = 3; normal_technique_common.accessor.stride = 3; normal_technique_common.accessor.param[0].name = "X"; normal_technique_common.accessor.param[0].type = "float"; normal_technique_common.accessor.param[1].name = "Y"; normal_technique_common.accessor.param[1].type = "float"; normal_technique_common.accessor.param[2].name = "Z"; normal_technique_common.accessor.param[2].type = "float"; uv_float_array.id = "Plane001-UV0-array"; uv_float_array.count = 6; uv_float_array.Values = new double[uv_float_array.count]; uv_float_array.Values[0] = 1.0000f; uv_float_array.Values[1] = 0.0000f; uv_float_array.Values[2] = 0.0000f; uv_float_array.Values[3] = 0.0000f; uv_float_array.Values[4] = 1.0000f; uv_float_array.Values[5] = 1.0000f; uv_technique_common.accessor = new accessor(); uv_technique_common.accessor.param = new param[2]; uv_technique_common.accessor.param[0] = new param(); uv_technique_common.accessor.param[1] = new param(); uv_technique_common.accessor.source = "#" + uv_float_array.id; uv_technique_common.accessor.count = 3; uv_technique_common.accessor.stride = 2; uv_technique_common.accessor.param[0].name = "S"; uv_technique_common.accessor.param[0].type = "float"; uv_technique_common.accessor.param[1].name = "T"; uv_technique_common.accessor.param[1].type = "float"; geomMesh.source[0].id = "Plane001-POSITION"; geomMesh.source[0].Item = position_float_array; geomMesh.source[0].technique_common = position_technique_common; geomMesh.source[1].id = "Plane001-Normal0"; geomMesh.source[1].Item = normal_float_array; geomMesh.source[1].technique_common = normal_technique_common; geomMesh.source[2].id = "Plane001-UV0"; geomMesh.source[2].Item = uv_float_array; geomMesh.source[2].technique_common = uv_technique_common; geomMesh.vertices = new vertices(); geomMesh.vertices.input[0] = new InputLocal(); geomMesh.vertices.input[0].semantic = "POSITION"; geomMesh.vertices.input[0].source = "#Plane001-POSITION"; geomMesh.vertices.id = "Plane001-VERTEX"; triangles meshTriangle = new triangles(); meshTriangle.count = 1; meshTriangle.input = new InputLocalOffset[3]; meshTriangle.input[0] = new InputLocalOffset(); meshTriangle.input[1] = new InputLocalOffset(); meshTriangle.input[2] = new InputLocalOffset(); meshTriangle.input[0].semantic = "VERTEX"; meshTriangle.input[0].offset = 0; meshTriangle.input[0].source = "#Plane001-VERTEX"; meshTriangle.input[1].semantic = "NORMAL"; meshTriangle.input[1].offset = 1; meshTriangle.input[1].source = "#Plane001-Normal0"; meshTriangle.input[2].semantic = "TEXCOORD"; meshTriangle.input[2].offset = 2; meshTriangle.input[2].set = 0; meshTriangle.input[2].source = "#Plane001-UV0"; string p = ""; int[] pArray = new int[9]; pArray[0] = 0; pArray[1] = 0; pArray[2] = 0; pArray[3] = 1; pArray[4] = 1; pArray[5] = 1; pArray[6] = 2; pArray[7] = 2; pArray[8] = 2; foreach (var data in pArray) { if (data is int) { p += " " + data.ToString(); } } meshTriangle.p = p; geomMesh.Items = new object[1]; geomMesh.Items[0] = new object(); geomMesh.Items[0] = meshTriangle; geom.Item = geomMesh; geom.id = "Plane001-lib"; geom.name = "Plane001Mesh"; library_geom.geometry[0] = geom; // library_visual_scenes library_visual_scenes lib_visual_scene = new library_visual_scenes(); lib_visual_scene.visual_scene = new visual_scene[1]; lib_visual_scene.visual_scene[0] = new visual_scene(); visual_scene visaul = new visual_scene(); visaul.node = new node[1]; visaul.node[0] = new node(); visaul.node[0].name = "Triangle001"; visaul.node[0].id = "Triangle001"; visaul.node[0].sid = "Triangle001"; visaul.node[0].instance_geometry = new instance_geometry[1]; visaul.node[0].instance_geometry[0] = new instance_geometry(); visaul.node[0].instance_geometry[0].url = "#Plane001-lib"; visaul.node[0].extra = new extra[1]; visaul.node[0].extra[0] = new extra(); visaul.node[0].extra[0].technique = new technique[1]; visaul.node[0].extra[0].technique[0] = new technique(); visaul.node[0].extra[0].technique[0].profile = "FCOLLADA"; visaul.name = "cube"; visaul.id = "cube"; lib_visual_scene.visual_scene[0] = visaul; model.Items = new object[2]; model.Items[0] = library_geom; model.Items[1] = lib_visual_scene; model.scene = new COLLADAScene(); model.scene.instance_visual_scene = new InstanceWithExtra(); model.scene.instance_visual_scene.url = "#" + visaul.id; model.Save("C:\\ProgramData\\Autodesk\\revit\\Addins\\2020\\dd.dae"); return(0); }
internal DAEGeometry(DAELoaderNode loader, geometry geo) { if (geo.Item == null || !(geo.Item is mesh)) { // empty or not supported geometry return; } mesh m = geo.Item as mesh; // load sources Dictionary <string, MeshSource> sources = new Dictionary <string, MeshSource>(); foreach (source src in m.source) { if (src.Item is float_array) { float_array values = src.Item as float_array; int stride = (int)src.technique_common.accessor.stride; sources.Add(src.id, new MeshSource(values.Values, stride)); } } // load positions foreach (InputLocal input in m.vertices.input) { if (input.semantic.Equals("POSITION")) { sources.Add(m.vertices.id, sources[DAEUtils.GetUrl(input.source).Id]); break; } } // load primitives foreach (var item in m.Items) { // load triangles if (item is triangles) { triangles tris = item as triangles; DAEVertexDescription[] vertices = new DAEVertexDescription[tris.count * 3]; int[] p = DAEUtils.StringToIntArray(tris.p); int stepSize = p.Length / ((int)tris.count * 3); foreach (InputLocalOffset input in tris.input) { SetVertices(input, p, stepSize, sources, vertices); } if (!ContainsTangents(tris.input)) { GenerateMeshTangents(vertices); } _triangles.Add(new DAETriangles(loader, vertices, tris.material)); } else if (item is polylist) { polylist polys = item as polylist; int[] polyVertexCounts = DAEUtils.StringToIntArray(polys.vcount); int vertexCount = 0; int triCount = 0; for (int i = 0; i < polyVertexCounts.Length; i++) { vertexCount += polyVertexCounts[i]; triCount += polyVertexCounts[i] - 2; } DAEVertexDescription[] polyVertices = new DAEVertexDescription[vertexCount]; int[] p = DAEUtils.StringToIntArray(polys.p); int stepSize = p.Length / vertexCount; foreach (InputLocalOffset input in polys.input) { SetVertices(input, p, stepSize, sources, polyVertices); } // triangulation DAEVertexDescription[] triVertices = new DAEVertexDescription[triCount * 3]; int triVertexIdx = 0; int polyVertexIdx = 0; for (int i = 0; i < polyVertexCounts.Length; i++) { int triVertex = 0; for (int k = 0; k < polyVertexCounts[i]; k++) { if (triVertex == 3) { triVertex = 1; k--; // repeat first vertex triVertices[triVertexIdx++] = polyVertices[polyVertexIdx]; } triVertices[triVertexIdx++] = polyVertices[polyVertexIdx + k]; triVertex++; } // skip to next polygon polyVertexIdx += polyVertexCounts[i]; } if (!ContainsTangents(polys.input)) { GenerateMeshTangents(triVertices); } _triangles.Add(new DAETriangles(loader, triVertices, polys.material)); } } }
public void ImportFromCollada(mesh mesh, VertexDescriptor vertexFormat, bool isSkinned, ExporterOptions options) { Options = options; Mesh = mesh; ImportSources(); ImportFaces(); if (vertexFormat == null) { vertexFormat = FindVertexFormat(isSkinned); } InputVertexType = vertexFormat; OutputVertexType = new VertexDescriptor { HasPosition = InputVertexType.HasPosition, HasBoneWeights = InputVertexType.HasBoneWeights, NumBoneInfluences = InputVertexType.NumBoneInfluences, NormalType = InputVertexType.NormalType, TangentType = InputVertexType.TangentType, BinormalType = InputVertexType.BinormalType, ColorMapType = InputVertexType.ColorMapType, ColorMaps = InputVertexType.ColorMaps, TextureCoordinateType = InputVertexType.TextureCoordinateType, TextureCoordinates = InputVertexType.TextureCoordinates }; ImportVertices(); // TODO: This should be done before deduplication! // TODO: Move this to somewhere else ... ? if (!HasNormals || Options.RecalculateNormals) { if (!HasNormals) { Utils.Info(String.Format("Channel 'NORMAL' not found, will rebuild vertex normals after import.")); } HasNormals = true; OutputVertexType.NormalType = NormalType.Float3; computeNormals(); } ImportColors(); ImportUVs(); if (UVInputIndices.Count() > 0 || ColorInputIndices.Count() > 0 || NormalsInputIndex != -1 || TangentsInputIndex != -1 || BinormalsInputIndex != -1) { var outVertexIndices = new Dictionary <int[], int>(new VertexIndexComparer()); ConsolidatedIndices = new List <int>(TriangleCount * 3); ConsolidatedVertices = new List <Vertex>(Vertices.Count); OriginalToConsolidatedVertexIndexMap = new Dictionary <int, List <int> >(); for (var vert = 0; vert < TriangleCount * 3; vert++) { var index = new int[InputOffsetCount]; for (var i = 0; i < InputOffsetCount; i++) { index[i] = Indices[vert * InputOffsetCount + i]; } int consolidatedIndex; if (!outVertexIndices.TryGetValue(index, out consolidatedIndex)) { var vertexIndex = index[VertexInputIndex]; consolidatedIndex = ConsolidatedVertices.Count; Vertex vertex = Vertices[vertexIndex].Clone(); if (NormalsInputIndex != -1) { vertex.Normal = Normals[index[NormalsInputIndex]]; } if (TangentsInputIndex != -1) { vertex.Tangent = Tangents[index[TangentsInputIndex]]; } if (BinormalsInputIndex != -1) { vertex.Binormal = Binormals[index[BinormalsInputIndex]]; } for (int uv = 0; uv < UVInputIndices.Count(); uv++) { vertex.SetUV(uv, UVs[uv][index[UVInputIndices[uv]]]); } for (int color = 0; color < ColorInputIndices.Count(); color++) { vertex.SetColor(color, Colors[color][index[ColorInputIndices[color]]]); } outVertexIndices.Add(index, consolidatedIndex); ConsolidatedVertices.Add(vertex); List <int> mappedIndices = null; if (!OriginalToConsolidatedVertexIndexMap.TryGetValue(vertexIndex, out mappedIndices)) { mappedIndices = new List <int>(); OriginalToConsolidatedVertexIndexMap.Add(vertexIndex, mappedIndices); } mappedIndices.Add(consolidatedIndex); } ConsolidatedIndices.Add(consolidatedIndex); } Utils.Info(String.Format("Merged {0} vertices into {1} output vertices", Vertices.Count, ConsolidatedVertices.Count)); } else { Utils.Info(String.Format("Mesh has no separate normals, colors or UV map, vertex consolidation step skipped.")); ConsolidatedVertices = Vertices; ConsolidatedIndices = new List <int>(TriangleCount * 3); for (var vert = 0; vert < TriangleCount * 3; vert++) { ConsolidatedIndices.Add(VertexIndex(vert)); } OriginalToConsolidatedVertexIndexMap = new Dictionary <int, List <int> >(); for (var i = 0; i < Vertices.Count; i++) { OriginalToConsolidatedVertexIndexMap.Add(i, new List <int> { i }); } } if ((InputVertexType.TangentType == NormalType.None || InputVertexType.BinormalType == NormalType.None) && ((!HasTangents && UVs.Count > 0) || Options.RecalculateTangents)) { if (!HasTangents) { Utils.Info(String.Format("Channel 'TANGENT'/'BINROMAL' not found, will rebuild vertex tangents after import.")); } OutputVertexType.TangentType = NormalType.Float3; OutputVertexType.BinormalType = NormalType.Float3; HasTangents = true; computeTangents(); } // Use optimized tangent, texture map and color map format when exporting for D:OS 2 if ((Options.ModelInfoFormat == DivinityModelInfoFormat.LSMv0 || Options.ModelInfoFormat == DivinityModelInfoFormat.LSMv1) && HasNormals && HasTangents) { OutputVertexType.NormalType = NormalType.QTangent; OutputVertexType.TangentType = NormalType.QTangent; OutputVertexType.BinormalType = NormalType.QTangent; if (OutputVertexType.TextureCoordinateType == TextureCoordinateType.Float2) { OutputVertexType.TextureCoordinateType = TextureCoordinateType.Half2; } if (OutputVertexType.ColorMapType == ColorMapType.Float4) { OutputVertexType.ColorMapType = ColorMapType.Byte4; } } }
void AddPositions(out Vector3 scale, out Vector3 offset, mesh mesh, ModelPrim prim, Matrix4 transform) { prim.Positions = new List <Vector3>(); source posSrc = FindSource(mesh.source, mesh.vertices.input[0].source); double[] posVals = ((float_array)posSrc.Item).Values; for (int i = 0; i < posVals.Length / 3; i++) { Vector3 pos = new Vector3((float)posVals[i * 3], (float)posVals[i * 3 + 1], (float)posVals[i * 3 + 2]); pos = Vector3.Transform(pos, transform); prim.Positions.Add(pos); } prim.BoundMin = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue); prim.BoundMax = new Vector3(float.MinValue, float.MinValue, float.MinValue); foreach (var pos in prim.Positions) { if (pos.X > prim.BoundMax.X) { prim.BoundMax.X = pos.X; } if (pos.Y > prim.BoundMax.Y) { prim.BoundMax.Y = pos.Y; } if (pos.Z > prim.BoundMax.Z) { prim.BoundMax.Z = pos.Z; } if (pos.X < prim.BoundMin.X) { prim.BoundMin.X = pos.X; } if (pos.Y < prim.BoundMin.Y) { prim.BoundMin.Y = pos.Y; } if (pos.Z < prim.BoundMin.Z) { prim.BoundMin.Z = pos.Z; } } scale = prim.BoundMax - prim.BoundMin; offset = prim.BoundMin + (scale / 2); // Fit vertex positions into identity cube -0.5 .. 0.5 for (int i = 0; i < prim.Positions.Count; i++) { Vector3 pos = prim.Positions[i]; pos = new Vector3( scale.X == 0 ? 0 : ((pos.X - prim.BoundMin.X) / scale.X) - 0.5f, scale.Y == 0 ? 0 : ((pos.Y - prim.BoundMin.Y) / scale.Y) - 0.5f, scale.Z == 0 ? 0 : ((pos.Z - prim.BoundMin.Z) / scale.Z) - 0.5f ); prim.Positions[i] = pos; } }
=> Create(mesh, triangles, vertices, Vertex.Descriptors(Allocator.Temp));
private static geometry SerializeModel(Geometry geometry_section, Topology topology_section, Model model_data, string id) { string VERT_ID = "vertices-" + id; string NORM_ID = "norms-" + id; string UV_ID = "uv-" + id; string RAW_VERT_ID = "vert_raw-" + id; int vertlen = geometry_section.verts.Count; int normlen = geometry_section.normals.Count; int uvlen = geometry_section.uvs.Count; triangles triangles = new triangles(); List <InputLocalOffset> inputs = new List <InputLocalOffset>(); inputs.Add(new InputLocalOffset { semantic = "VERTEX", source = "#" + VERT_ID, offset = 0, }); if (normlen > 0) { inputs.Add(new InputLocalOffset { semantic = "NORMAL", source = "#" + NORM_ID, offset = 0, }); } if (uvlen > 0) { inputs.Add(new InputLocalOffset { semantic = "TEXCOORD", source = "#" + UV_ID, offset = 0, set = 1, // IDK what this does or why we need it }); } triangles.input = inputs.ToArray(); mesh mesh = new mesh { vertices = new vertices { id = VERT_ID, input = new InputLocal[] { new InputLocal { semantic = "POSITION", source = "#" + RAW_VERT_ID } } }, Items = new object[] { triangles } }; StringBuilder facesData = new StringBuilder("\n"); // Start on a newline foreach (Face face in topology_section.facelist) { if (!face.BoundsCheck(vertlen)) { throw new Exception("Vert Out Of Bounds!"); } if (normlen > 0 && !face.BoundsCheck(normlen)) { throw new Exception("Norm Out Of Bounds!"); } if (uvlen > 0 && !face.BoundsCheck(uvlen)) { throw new Exception("UV Out Of Bounds!"); } // This set is used for the Vertices, Normals and UVs, as they all have the same indexes // A bit inefficent in terms of storage space, but easier to implement as that's how it's // handled inside the Diesel model files and making a index remapper thing would be a pain. facesData.AppendFormat("{0} {1} {2}\n", face.a, face.b, face.c); triangles.count++; } triangles.p = facesData.ToString(); List <source> sources = new List <source>(); sources.Add(GenerateSource(RAW_VERT_ID, geometry_section.verts)); if (normlen > 0) { sources.Add(GenerateSource(NORM_ID, geometry_section.normals)); } if (uvlen > 0) { sources.Add(GenerateSourceTex(UV_ID, geometry_section.uvs)); } mesh.source = sources.ToArray(); return(new geometry { name = "Diesel Converted Model " + id, id = "model-geom-" + id, Item = mesh }); }
void AddFacesFromPolyList(polylist list, mesh mesh, ModelPrim prim, Matrix4 transform) { string material = list.material; source posSrc = null; source normalSrc = null; source uvSrc = null; ulong stride = 0; int posOffset = -1; int norOffset = -1; int uvOffset = -1; foreach (var inp in list.input) { stride = Math.Max(stride, inp.offset); switch (inp.semantic) { case "VERTEX": posSrc = FindSource(mesh.source, mesh.vertices.input[0].source); posOffset = (int)inp.offset; break; case "NORMAL": normalSrc = FindSource(mesh.source, inp.source); norOffset = (int)inp.offset; break; case "TEXCOORD": uvSrc = FindSource(mesh.source, inp.source); uvOffset = (int)inp.offset; break; } } stride += 1; if (posSrc == null) { return; } var vcount = StrToArray(list.vcount); var idx = StrToArray(list.p); Vector3[] normals = null; if (normalSrc != null) { var norVal = ((float_array)normalSrc.Item).Values; normals = new Vector3[norVal.Length / 3]; for (int i = 0; i < normals.Length; i++) { normals[i] = new Vector3((float)norVal[i * 3 + 0], (float)norVal[i * 3 + 1], (float)norVal[i * 3 + 2]); normals[i] = Vector3.TransformNormal(normals[i], transform); normals[i].Normalize(); } } Vector2[] uvs = null; if (uvSrc != null) { var uvVal = ((float_array)uvSrc.Item).Values; uvs = new Vector2[uvVal.Length / 2]; for (int i = 0; i < uvs.Length; i++) { uvs[i] = new Vector2((float)uvVal[i * 2 + 0], (float)uvVal[i * 2 + 1]); } } ModelFace face = new ModelFace { MaterialID = list.material }; if (face.MaterialID != null) { if (MatSymTarget.ContainsKey(list.material)) { ModelMaterial mat = Materials.Find(m => m.ID == MatSymTarget[list.material]); if (mat != null) { face.Material = mat; } } } int curIdx = 0; foreach (var nvert in vcount) { if (nvert < 3 || nvert > 4) { throw new InvalidDataException("Only triangles and quads supported"); } Vertex[] verts = new Vertex[nvert]; for (int j = 0; j < nvert; j++) { verts[j].Position = prim.Positions[idx[curIdx + posOffset + (int)stride * j]]; if (normals != null) { verts[j].Normal = normals[idx[curIdx + norOffset + (int)stride * j]]; } if (uvs != null) { verts[j].TexCoord = uvs[idx[curIdx + uvOffset + (int)stride * j]]; } } switch (nvert) { case 3: face.AddVertex(verts[0]); face.AddVertex(verts[1]); face.AddVertex(verts[2]); break; case 4: face.AddVertex(verts[0]); face.AddVertex(verts[1]); face.AddVertex(verts[2]); face.AddVertex(verts[0]); face.AddVertex(verts[2]); face.AddVertex(verts[3]); break; } curIdx += (int)stride * nvert; } prim.Faces.Add(face); }
public mesh ExportToCollada(ExporterOptions options) { // TODO: model transform/inverse transform? source vertexSource = null; var sources = new List <source>(); ulong inputOffset = 0; var inputs = new List <InputLocal>(); var inputOffsets = new List <InputLocalOffset>(); foreach (var component in PrimaryVertexData.VertexComponentNames) { var input = new InputLocal(); source source = null; switch (component.String) { case "Position": { source = PrimaryVertexData.MakeColladaPositions(Name); vertexSource = source; input.semantic = "POSITION"; var vertexInputOff = new InputLocalOffset(); vertexInputOff.semantic = "VERTEX"; vertexInputOff.source = "#" + source.id; vertexInputOff.offset = inputOffset++; inputOffsets.Add(vertexInputOff); break; } case "Normal": { if (options.ExportNormals) { source = PrimaryVertexData.MakeColladaNormals(Name); input.semantic = "NORMAL"; } break; } case "Tangent": { if (options.ExportTangents) { source = PrimaryVertexData.MakeColladaTangents(Name); input.semantic = "TANGENT"; } break; } case "Binormal": { if (options.ExportTangents) { source = PrimaryVertexData.MakeColladaBinormals(Name); input.semantic = "BINORMAL"; } break; } case "MaxChannel_1": case "MaxChannel_2": case "UVChannel_1": case "UVChannel_2": { if (options.ExportUVs) { int uvIndex = Int32.Parse(component.String.Substring(11)) - 1; source = PrimaryVertexData.MakeColladaUVs(Name, uvIndex); var texInputOff = new InputLocalOffset(); texInputOff.semantic = "TEXCOORD"; texInputOff.source = "#" + source.id; texInputOff.offset = inputOffset++; inputOffsets.Add(texInputOff); } break; } case "BoneWeights": case "BoneIndices": // These are handled in ExportSkin() break; case "DiffuseColor0": case "map1": // Possibly bogus D:OS name for DiffuseColor0 // TODO: This is not exported at the moment. break; default: throw new NotImplementedException("Vertex component not supported: " + component.String); } if (source != null) { sources.Add(source); } if (input.semantic != null) { input.source = "#" + source.id; inputs.Add(input); } } var triangles = PrimaryTopology.MakeColladaTriangles( inputOffsets.ToArray(), PrimaryVertexData.Deduplicator.VertexDeduplicationMap, PrimaryVertexData.Deduplicator.UVDeduplicationMaps ); var colladaMesh = new mesh(); colladaMesh.vertices = new vertices(); colladaMesh.vertices.id = Name + "-vertices"; colladaMesh.vertices.input = inputs.ToArray(); colladaMesh.source = sources.ToArray(); colladaMesh.Items = new object[] { triangles }; return(colladaMesh); }