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); }
public static void Main() { //main method geometry MyGeometry = new geometry(); Console.Write("Enter the radius of your circle: "); int radius = Convert.ToInt32(Console.ReadLine()); double radiusTwo = MyGeometry.circleArea(radius); Console.WriteLine("\nThe area is {0:f3}", radiusTwo); //wait Console.WriteLine(' '); //wait Console.WriteLine("Enter the height and base of your triangle: "); float triangleBase = Convert.ToInt32(Console.ReadLine()); float triangleHeight = Convert.ToInt32(Console.ReadLine()); float triangleTotal = MyGeometry.triangleArea(triangleBase, triangleHeight); Console.Write("\nThe area is {0:f3}", triangleTotal); //wait Console.WriteLine(' '); //wait Console.WriteLine("Enter the height pyramid: "); float pyramidHeight = Convert.ToInt32(Console.ReadLine()); float pyramidTotal = MyGeometry.pyramidVolume(pyramidHeight, triangleBase, triangleHeight); Console.Write("\nThe area is {0:f3}", pyramidTotal); }
private DAEGeometry CreateGeometry(DAELoaderNode loader, geometry geo) { DAEGeometry result = new DAEGeometry(loader, geo); _geometries.Add(geo.id, result); return(result); }
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); }
public static Node LoadHiearchy(Node parent, node daeNode, STGenericModel model, ColladaScene colladaScene) { Node node = new Node(parent); node.Name = daeNode.name; node.Type = daeNode.type; node.Transform = DaeUtility.GetMatrix(daeNode.Items) * parent.Transform; if (daeNode.instance_geometry != null) { geometry geom = DaeUtility.FindGeoemertyFromNode(daeNode, colladaScene.geometries); model.Meshes.Add(LoadMeshData(colladaScene, node, geom, colladaScene.materials)); } if (daeNode.instance_controller != null) { controller controller = DaeUtility.FindControllerFromNode(daeNode, colladaScene.controllers); geometry geom = DaeUtility.FindGeoemertyFromController(controller, colladaScene.geometries); model.Meshes.Add(LoadMeshData(colladaScene, node, geom, colladaScene.materials, controller)); } try { } catch (Exception ex) { throw new Exception($"Failed to convert mesh {daeNode.name} \n {ex.ToString()}"); } //Find the root bone if (node.Type == NodeType.JOINT) { //Apply axis rotation Matrix4 boneTransform = Matrix4.Identity; if (colladaScene.UpAxisType == UpAxisType.Y_UP) { // boneTransform = Matrix4.CreateRotationX(MathHelper.DegreesToRadians(90)); } if (colladaScene.UintSize != null && colladaScene.UintSize.meter != 1) { var scale = ApplyUintScaling(colladaScene, new Vector3(1)); boneTransform *= Matrix4.CreateScale(scale); } LoadBoneHiearchy(daeNode, model, null, ref boneTransform); } else if (daeNode.node1 != null) { foreach (node child in daeNode.node1) { node.Children.Add(LoadHiearchy(node, child, model, colladaScene)); } } return(node); }
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 ExportMeshBinding(Model model, string skelRef, MeshBinding meshBinding, List <geometry> geometries, List <controller> controllers, List <node> geomNodes) { var exporter = new ColladaMeshExporter(meshBinding.Mesh, Options); var mesh = exporter.Export(); var geom = new geometry(); geom.id = meshBinding.Mesh.Name + "-geom"; geom.name = meshBinding.Mesh.Name; geom.Item = mesh; geometries.Add(geom); bool hasSkin = skelRef != null && meshBinding.Mesh.IsSkinned(); skin skin = null; controller ctrl = null; if (hasSkin) { var boneNames = new Dictionary <string, Bone>(); foreach (var bone in model.Skeleton.Bones) { boneNames.Add(bone.Name, bone); } skin = ExportSkin(meshBinding.Mesh, model.Skeleton.Bones, boneNames, geom.id); ctrl = new controller(); ctrl.id = meshBinding.Mesh.Name + "-skin"; ctrl.name = meshBinding.Mesh.Name + "_Skin"; ctrl.Item = skin; controllers.Add(ctrl); } var geomNode = new node(); geomNode.id = geom.name + "-node"; geomNode.name = geom.name; geomNode.type = NodeType.NODE; if (hasSkin) { var controllerInstance = new instance_controller(); controllerInstance.url = "#" + ctrl.id; controllerInstance.skeleton = new string[] { "#" + skelRef }; geomNode.instance_controller = new instance_controller[] { controllerInstance }; } else { var geomInstance = new instance_geometry(); geomInstance.url = "#" + geom.id; geomNode.instance_geometry = new instance_geometry[] { geomInstance }; } geomNodes.Add(geomNode); }
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); } }
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 string FindVertexFormat(geometry geom) { string vertexFormat; // Use the override vertex format, if one was specified if (!Options.VertexFormats.TryGetValue(geom.name, out vertexFormat)) { vertexFormat = "P"; string attributeCounts = "3"; bool isSkinned = SkinnedMeshes.Contains(geom.id); if (isSkinned) { vertexFormat += "W"; attributeCounts += "4"; } // Granny doesn't have any skinned vertex formats without normals if (Options.ExportNormals || isSkinned) { vertexFormat += "N"; attributeCounts += "3"; } if (Options.ExportTangents) { vertexFormat += "GB"; attributeCounts += "33"; } if (Options.ExportUVs) { vertexFormat += "T"; attributeCounts += "2"; } vertexFormat += attributeCounts; } return(vertexFormat); }
protected void Page_Load(object sender, EventArgs e) { GPServer request = new GPServer(); spatialReference spR = new spatialReference(); List <features> featList = new List <features>(); features feat = new features(); geometry geometry = new geometry(); geometry.x = "748874.9600000003"; geometry.y = "1425623.8499999999}"; feat.geometry = geometry; featList.Add(feat); spR.wkid = "32647"; request.geometryType = "esriGeometryPoint"; request.spatialReference = spR; request.features = featList; string url = "http://pipelinegis/arcgis/rest/services/GEOPROCESSING/DA_LOCATE_KP_FROM_SERIES/GPServer"; ConvertX.GetRequest(url, request); }
private CollisionGroupNode LoadGroupsFromColladaRecursive(CollisionGroupNode parent, node dae_node, geometry[] meshes) { CollisionGroupNode new_node = new CollisionGroupNode(parent, dae_node.name); m_Nodes.Add(new_node); if (dae_node.instance_geometry != null) { string mesh_id = dae_node.instance_geometry[0].url.Trim('#'); geometry node_geo = Array.Find(meshes, x => x.id == mesh_id); LoadGeometryFromCollada(new_node, node_geo); } if (dae_node.node1 != null) { foreach (node n in dae_node.node1) { new_node.Children.Add(LoadGroupsFromColladaRecursive(new_node, n, meshes)); } } return(new_node); }
public static string ExportFile(FullModelData data, string path) { path = path.Replace(".model", ".dae"); List <SectionHeader> sections = data.sections; Dictionary <UInt32, ISection> parsed_sections = data.parsed_sections; byte[] leftover_data = data.leftover_data; // Set up the XML structure library_geometries libgeoms = new library_geometries(); library_visual_scenes libscenes = new library_visual_scenes(); COLLADAScene scene = new COLLADAScene { instance_visual_scene = new InstanceWithExtra { url = "#scene" } }; COLLADA collada = new COLLADA { Items = new object[] { libgeoms, libscenes }, scene = scene, asset = new asset { created = DateTime.UtcNow, modified = DateTime.UtcNow, // Otherwise it defaults to Y-up (see asset's constructor), while we're // using Z-up. Without the asset tag Blender defaults to Z-up, so if you // remove this then the presence of the asset tag flips the model. up_axis = UpAxisType.Z_UP, }, }; // Build the mesh List <geometry> geometries = new List <geometry>(); List <node> nodes = new List <node>(); int model_i = 0; foreach (SectionHeader sectionheader in sections) { if (sectionheader.type == model_data_tag) { Model model_data = (Model)parsed_sections[sectionheader.id]; if (model_data.version == 6) { continue; } model_i++; string model_id = model_i + "-" + model_data.HashName.String; PassthroughGP passthrough_section = model_data.PassthroughGP; Geometry geometry_section = passthrough_section.Geometry; Topology topology_section = passthrough_section.Topology; geometry geom = SerializeModel(geometry_section, topology_section, model_data, model_id); geometries.Add(geom); node root_node = new node { id = "model-" + model_id, name = "Model " + model_id, type = NodeType.NODE, instance_geometry = new instance_geometry[] { new instance_geometry { url = "#model-geom-" + model_id, name = "Model Geom" + model_id } } }; nodes.Add(root_node); if (model_data.SkinBones == null) { continue; } SkinBones sb = model_data.SkinBones; //Console.WriteLine(sb.bones); //Console.WriteLine(sb); node bone_root_node = new node { id = "model-" + model_id + "-boneroot", name = "Model " + model_id + " Bones", type = NodeType.NODE, /*Items = new object[] * { * new matrix * { * sid = "transform", // Apparently Blender really wants this * Values = MathUtil.Serialize(sb.unknown_matrix) * } * }, * ItemsElementName = new ItemsChoiceType2[] * { * ItemsChoiceType2.matrix * }*/ }; root_node.node1 = new node[] { bone_root_node }; Dictionary <Object3D, node> bones = new Dictionary <Object3D, node>(); // In order to find locators, which aren't present in the SkinBones // object, we check the child of each object we process. // // To then process those, we use a queue (to_parse) which lists the // objects in our TODO list to search. We draw from this as we process them. // // We also keep the list of what we have processed in (parsed), so we don't // process anything twice. // // TODO rewrite this code to be based around children, removing the need for a seperate // loop after this that arranges the heirachy of nodes. List <Object3D> parsed = new List <Object3D>(sb.Objects); Queue <Object3D> to_parse = new Queue <Object3D>(sb.Objects); int i = 0; while (to_parse.Count != 0) { Object3D obj = to_parse.Dequeue(); string bonename = obj.HashName.String; // Find the locators and such, and add them to the TODO list foreach (Object3D child in obj.children) { if (!parsed.Contains(child)) // Don't process something twice { parsed.Add(child); to_parse.Enqueue(child); } } Vector3 translate; Quaternion rotate; Vector3 scale; Matrix4x4.Decompose(obj.Transform, out scale, out rotate, out translate); Matrix4x4 final_rot = Matrix4x4.CreateFromQuaternion(rotate); final_rot.Translation = translate; if (obj.Parent == null || !sb.Objects.Contains(obj.Parent)) { Matrix4x4 fixed_obj_transform = obj.WorldTransform; Matrix4x4.Decompose(fixed_obj_transform, out scale, out rotate, out translate); // Fixes the head, but breaks the arms // For now, leave it like this //final_rot = final_rot.MultDiesel(fixed_obj_transform); } // If the object is not contained within the SkinBones // object, it must be a locator. bool locator = !sb.Objects.Contains(obj); // Add the node bones[obj] = new node { id = "model-" + model_id + "-bone-" + bonename, name = (locator ? "locator-" : "") + bonename, type = NodeType.JOINT, Items = new object[] { new matrix { sid = "transform", // Apparently Blender really wants this Values = MathUtil.Serialize(final_rot) }, }, ItemsElementName = new ItemsChoiceType2[] { ItemsChoiceType2.matrix } }; i++; } foreach (var(obj, nod) in bones) { node parent = bone_root_node; if (bones.ContainsKey(obj)) { parent = bones[obj.Parent]; } if (parent.node1 == null) { parent.node1 = new node[1]; } else { node[] children = parent.node1; Array.Resize(ref children, children.Length + 1); parent.node1 = children; } parent.node1[parent.node1.Length - 1] = nod; } } } libgeoms.geometry = geometries.ToArray(); libscenes.visual_scene = new visual_scene[] { new visual_scene { id = "scene", name = "Scene", node = nodes.ToArray() } }; using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write)) { collada.Save(fs); // Do we need this? // fs.Close(); } return(path); }
// return mesh id private string CreateMesh(Mesh mesh) { string id = ""; if (meshLookup.TryGetValue(mesh, out id)) { return(id); } var geometry = new geometry(); geometries.Add(geometry); id = CreateId(); geometry.id = id; var m = new mesh(); geometry.Item = m; m.source = new source[] { new source(), // position new source(), // normal new source(), // uvs }; m.source[0].id = CreateId(); var fa = new float_array(); fa.id = CreateId(); fa.Values = ToDoubleArray(mesh.vertices); fa.count = (ulong)fa.Values.Length; m.source[0].Item = fa; m.source[0].technique_common = new sourceTechnique_common(); m.source[0].technique_common.accessor = new accessor(); m.source[0].technique_common.accessor.count = fa.count / 3; m.source[0].technique_common.accessor.source = "#" + fa.id; m.source[0].technique_common.accessor.stride = 3; m.source[0].technique_common.accessor.param = new[] { new param(), new param(), new param() }; m.source[0].technique_common.accessor.param[0].name = "X"; m.source[0].technique_common.accessor.param[0].type = "float"; m.source[0].technique_common.accessor.param[1].name = "Y"; m.source[0].technique_common.accessor.param[1].type = "float"; m.source[0].technique_common.accessor.param[2].name = "Z"; m.source[0].technique_common.accessor.param[2].type = "float"; m.source[1].id = CreateId(); fa = new float_array(); fa.id = CreateId(); fa.Values = ToDoubleArray(mesh.normals); fa.count = (ulong)fa.Values.Length; m.source[1].Item = fa; m.source[1].technique_common = new sourceTechnique_common(); m.source[1].technique_common.accessor = new accessor(); m.source[1].technique_common.accessor.count = fa.count / 3; m.source[1].technique_common.accessor.source = "#" + fa.id; m.source[1].technique_common.accessor.stride = 3; m.source[1].technique_common.accessor.param = new[] { new param(), new param(), new param() }; m.source[1].technique_common.accessor.param[0].name = "X"; m.source[1].technique_common.accessor.param[0].type = "float"; m.source[1].technique_common.accessor.param[1].name = "Y"; m.source[1].technique_common.accessor.param[1].type = "float"; m.source[1].technique_common.accessor.param[2].name = "Z"; m.source[1].technique_common.accessor.param[2].type = "float"; m.source[2].id = CreateId(); fa = new float_array(); fa.id = CreateId(); fa.Values = ToDoubleArray(mesh.uv); fa.count = (ulong)fa.Values.Length; m.source[2].Item = fa; m.source[2].technique_common = new sourceTechnique_common(); m.source[2].technique_common.accessor = new accessor(); m.source[2].technique_common.accessor.count = fa.count / 2; m.source[2].technique_common.accessor.source = "#" + fa.id; m.source[2].technique_common.accessor.stride = 2; m.source[2].technique_common.accessor.param = new[] { new param(), new param() }; m.source[2].technique_common.accessor.param[0].name = "X"; m.source[2].technique_common.accessor.param[0].type = "float"; m.source[2].technique_common.accessor.param[1].name = "Y"; m.source[2].technique_common.accessor.param[1].type = "float"; m.vertices = new vertices(); m.vertices.id = CreateId(); m.vertices.input = new InputLocal[] { new InputLocal(), // position new InputLocal(), // normal new InputLocal() // uvs }; m.vertices.input[0].semantic = "POSITION"; m.vertices.input[0].source = "#" + m.source[0].id; m.vertices.input[1].semantic = "NORMAL"; m.vertices.input[1].source = "#" + m.source[1].id; m.vertices.input[2].semantic = "TEXCOORD"; m.vertices.input[2].source = "#" + m.source[2].id; var triangles = new List <int>(); var stringWriter = new StringWriter(); for (int i = 0; i < mesh.subMeshCount; i++) { var t = mesh.GetTriangles(i); triangles.AddRange(t); for (int j = 0; j < t.Length; j = j + 3) { stringWriter.Write("{0} ", t[j]); stringWriter.Write("{0} ", t[j + 1]); stringWriter.Write("{0} ", t[j + 2]); } } var tris = new triangles(); tris.count = (ulong)(triangles.Count / 3); tris.material = defaultMaterialName; tris.input = new InputLocalOffset[] { new InputLocalOffset(), //new InputLocalOffset(), //new InputLocalOffset() }; tris.input[0].offset = 0; tris.input[0].semantic = "VERTEX"; tris.input[0].source = "#" + m.vertices.id; // <input semantic="TEXCOORD" source="#Cube-mesh-map-0" offset="2" set="0"/> /*tris.input[1].offset = 1; * tris.input[1].semantic = "NORMAL"; * tris.input[1].source= "#"+m.source[1].id; * * tris.input[2].offset = 2; * tris.input[2].semantic = "TEXCOORD"; * tris.input[2].source= "#"+m.source[2].id; * tris.input[2].set = 0; * tris.input[2].setSpecified = true;*/ tris.p = stringWriter.ToString(); m.Items = new object[] { tris }; meshLookup[mesh] = id; return(id); }
public static void ExportIOModelAsDAE(string FileName, IOModel m) { COLLADA colladaFile = new COLLADA(); List <geometry> list_geometries = new List <geometry>(m.Meshes.Count); if (m.HasMeshes) { foreach (IOMesh iomesh in m.Meshes) { geometry g = new geometry(); g.name = iomesh.Name; g.id = iomesh.Name + $"_{m.Meshes.IndexOf(iomesh)}"; List <double> list_positions = new List <double>(); List <double> list_normals = new List <double>(); List <double> list_uvs = new List <double>(); List <double> list_colors = new List <double>(); foreach (IOVertex v in iomesh.Vertices) { list_positions.Add(v.Position.X); list_positions.Add(v.Position.Y); list_positions.Add(v.Position.Z); list_normals.Add(v.Normal.X); list_normals.Add(v.Normal.Y); list_normals.Add(v.Normal.Z); list_uvs.Add(v.UV0.X); list_uvs.Add(v.UV0.Y); } // Position source source_position = new source(); { float_array floats = new float_array(); floats.count = (ulong)list_positions.Count; floats.id = g.id + "_pos_arr"; floats.Values = list_positions.ToArray(); source_position = CreateSource(list_positions.Count, 3, floats.id, floats, new param[] { new param() { name = "X", type = "float" }, new param() { name = "Y", type = "float" }, new param() { name = "Z", type = "float" } }); } // Normal source source_normal = new source(); { float_array floats = new float_array(); floats.count = (ulong)list_normals.Count; floats.id = g.id + "_nrm_arr"; floats.Values = list_normals.ToArray(); source_normal = CreateSource(list_normals.Count, 3, floats.id, floats, new param[] { new param() { name = "X", type = "float" }, new param() { name = "Y", type = "float" }, new param() { name = "Z", type = "float" } }); } // UV0 source source_uv0 = new source(); { float_array floats = new float_array(); floats.count = (ulong)list_uvs.Count; floats.id = g.id + "_uv0_arr"; floats.Values = list_uvs.ToArray(); source_uv0 = CreateSource(list_uvs.Count, 2, floats.id, floats, new param[] { new param() { name = "S", type = "float" }, new param() { name = "T", type = "float" } }); } // vertices vertices vertices = new vertices(); vertices.id = g.id + "_verts"; vertices.input = new InputLocal[] { new InputLocal() { source = "#" + source_position.id, semantic = "POSITION" }, new InputLocal() { source = "#" + source_normal.id, semantic = "NORMAL" }, new InputLocal() { source = "#" + source_uv0.id, semantic = "TEXCOORD" } }; // triangles triangles triangles = new triangles(); triangles.count = (ulong)iomesh.Indices.Count; triangles.input = new InputLocalOffset[] { new InputLocalOffset() { offset = 0, semantic = "VERTEX", source = "#" + vertices.id } }; triangles.p = string.Join(" ", iomesh.Indices); // creating mesh mesh geomesh = new mesh(); geomesh.source = new source[] { source_position, source_normal, source_uv0 }; geomesh.Items = new object[] { triangles }; geomesh.vertices = vertices; g.Item = geomesh; list_geometries.Add(g); } } library_geometries lib_geometry = new library_geometries(); lib_geometry.geometry = list_geometries.ToArray(); // controllers List <controller> list_controller = new List <controller>(); if (m.HasMeshes && m.HasSkeleton) { // create lists List <source> skinSources = new List <source>(); List <string> boneNames = new List <string>(); List <double> InverseBinds = new List <double>(); foreach (RBone b in m.Skeleton.Bones) { boneNames.Add(b.Name); InverseBinds.AddRange(new double[] { b.InvWorldTransform.M11, b.InvWorldTransform.M21, b.InvWorldTransform.M31, b.InvWorldTransform.M41, b.InvWorldTransform.M12, b.InvWorldTransform.M22, b.InvWorldTransform.M32, b.InvWorldTransform.M42, b.InvWorldTransform.M13, b.InvWorldTransform.M23, b.InvWorldTransform.M33, b.InvWorldTransform.M43, b.InvWorldTransform.M14, b.InvWorldTransform.M24, b.InvWorldTransform.M34, b.InvWorldTransform.M44, }); } // setup controllers foreach (IOMesh iomesh in m.Meshes) { controller controller = new controller() { id = iomesh.Name + "_" + m.Meshes.IndexOf(iomesh) + "_controller" }; list_controller.Add(controller); // create source for weights List <double> weights = new List <double>(); List <int> bones = new List <int>(); List <int> boneCount = new List <int>(); StringBuilder build_v = new StringBuilder(); foreach (IOVertex v in iomesh.Vertices) { int bcount = 0; if (v.BoneWeights.X > 0) { if (!weights.Contains(v.BoneWeights.X)) { weights.Add(v.BoneWeights.X); } build_v.Append($"{(int)v.BoneIndices.X} {weights.IndexOf(v.BoneWeights.X)} "); bcount++; } if (v.BoneWeights.Y > 0) { if (!weights.Contains(v.BoneWeights.Y)) { weights.Add(v.BoneWeights.Y); } build_v.Append($"{(int)v.BoneIndices.Y} {weights.IndexOf(v.BoneWeights.Y)} "); bcount++; } if (v.BoneWeights.Z > 0) { if (!weights.Contains(v.BoneWeights.Z)) { weights.Add(v.BoneWeights.Z); } build_v.Append($"{(int)v.BoneIndices.Z} {weights.IndexOf(v.BoneWeights.Z)} "); bcount++; } if (v.BoneWeights.W > 0) { if (!weights.Contains(v.BoneWeights.W)) { weights.Add(v.BoneWeights.W); } build_v.Append($"{(int)v.BoneIndices.W} {weights.IndexOf(v.BoneWeights.W)} "); bcount++; } boneCount.Add(bcount); } // skin Name_array arr_name = new Name_array(); arr_name.count = (ulong)boneNames.Count; arr_name.id = controller.id + "joints"; arr_name.Values = boneNames.ToArray(); source source_skin = CreateSource(boneNames.Count, 1, arr_name.id, arr_name, new param[] { new param() { name = "JOINT", type = "name" } }); // bind float_array arr_bind = new float_array(); arr_bind.count = (ulong)InverseBinds.Count; arr_bind.id = controller.id + "binds"; arr_bind.Values = InverseBinds.ToArray(); source source_binds = CreateSource(InverseBinds.Count, 16, arr_bind.id, arr_bind, new param[] { new param() { name = "TRANSFORM", type = "float4x4" } }); // weight source source_weight = new source(); { float_array floats = new float_array(); floats.count = (ulong)weights.Count; floats.id = controller.id + "_weights"; floats.Values = weights.ToArray(); source_weight = CreateSource(weights.Count, 1, floats.id, floats, new param[] { new param() { name = "WEIGHT", type = "float" }, }); } skin skin = new skin(); skin.source1 = "#" + iomesh.Name + $"_{m.Meshes.IndexOf(iomesh)}"; skin.source = new source[] { source_skin, source_binds, source_weight }; skin.joints = new skinJoints() { input = new InputLocal[] { new InputLocal() { semantic = "JOINT", source = "#" + source_skin.id }, new InputLocal() { semantic = "INV_BIND_MATRIX", source = "#" + source_binds.id } } }; //skin weights skin.vertex_weights = new skinVertex_weights(); skin.vertex_weights.count = (ulong)iomesh.Vertices.Count; skin.vertex_weights.input = new InputLocalOffset[] { new InputLocalOffset() { semantic = "JOINT", source = "#" + source_skin.id, offset = 0 }, new InputLocalOffset() { semantic = "WEIGHT", source = "#" + source_weight.id, offset = 1 } }; skin.vertex_weights.vcount = string.Join(" ", boneCount); skin.vertex_weights.v = build_v.ToString(); controller.Item = skin; } } library_controllers lib_controllers = new library_controllers(); lib_controllers.controller = list_controller.ToArray(); // scene nodes List <node> scene_nodes = new List <node>(); int visual_index = 0; if (m.HasSkeleton) { Dictionary <RBone, node> boneToNode = new Dictionary <RBone, node>(); foreach (RBone b in m.Skeleton.Bones) { // create bone node node node = new node(); node.name = b.Name; node.id = "bone" + visual_index++; node.sid = b.Name; node.type = NodeType.JOINT; // add transform matrix mat = new matrix() { Values = new double[] { b.Transform.M11, b.Transform.M21, b.Transform.M31, b.Transform.M41, b.Transform.M12, b.Transform.M22, b.Transform.M32, b.Transform.M42, b.Transform.M13, b.Transform.M23, b.Transform.M33, b.Transform.M43, b.Transform.M14, b.Transform.M24, b.Transform.M34, b.Transform.M44, } }; node.ItemsElementName = new ItemsChoiceType2[] { ItemsChoiceType2.matrix }; node.Items = new object[] { mat }; // deal with parenting boneToNode.Add(b, node); if (b.ParentID == -1) { scene_nodes.Add(node); } else { if (boneToNode[m.Skeleton.Bones[b.ParentID]].node1 == null) { boneToNode[m.Skeleton.Bones[b.ParentID]].node1 = new node[0]; } node[] parentnode = boneToNode[m.Skeleton.Bones[b.ParentID]].node1; Array.Resize <node>(ref parentnode, parentnode.Length + 1); parentnode[parentnode.Length - 1] = node; boneToNode[m.Skeleton.Bones[b.ParentID]].node1 = parentnode; } } } if (m.HasMeshes) { foreach (IOMesh iomesh in m.Meshes) { node node = new node() { id = "mesh" + visual_index++, name = iomesh.Name, type = NodeType.NODE }; if (m.HasSkeleton) { instance_controller controller = new instance_controller() { url = iomesh.Name + "_" + m.Meshes.IndexOf(iomesh) + "_controller" }; controller.skeleton = new string[] { "#bone0" }; node.instance_controller = new instance_controller[] { controller }; } scene_nodes.Add(node); } } // visual scene root library_visual_scenes scenes = new library_visual_scenes(); scenes.visual_scene = new visual_scene[] { new visual_scene() { id = "visualscene0", name = "rdmscene" } }; scenes.visual_scene[0].node = scene_nodes.ToArray(); // scene COLLADAScene scene = new COLLADAScene(); scene.instance_visual_scene = new InstanceWithExtra() { url = "#visualscene0" }; // putting it all together colladaFile.Items = new object[] { lib_geometry, lib_controllers, scenes }; colladaFile.scene = scene; colladaFile.Save(FileName); }
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()
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); }
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)); } } }
// return mesh id private string CreateMeshWithSubmeshes(Mesh mesh, List <string> materialNames) { string id = ""; if (meshLookup.TryGetValue(mesh, out id)) { return(id); } var geometry = new geometry(); geometries.Add(geometry); id = CreateId(); geometry.id = id; var m = new mesh(); geometry.Item = m; m.source = new source[] { new source(), // position new source(), // normal new source(), // uvs }; m.source[0].id = CreateId(); var fa = new float_array(); fa.id = CreateId(); fa.Values = ToDoubleArray(mesh.vertices); fa.count = (ulong)fa.Values.Length; m.source[0].Item = fa; m.source[0].technique_common = new sourceTechnique_common(); m.source[0].technique_common.accessor = new accessor(); m.source[0].technique_common.accessor.count = fa.count / 3; m.source[0].technique_common.accessor.source = "#" + fa.id; m.source[0].technique_common.accessor.stride = 3; m.source[0].technique_common.accessor.param = new[] { new param(), new param(), new param() }; m.source[0].technique_common.accessor.param[0].name = "X"; m.source[0].technique_common.accessor.param[0].type = "float"; m.source[0].technique_common.accessor.param[1].name = "Y"; m.source[0].technique_common.accessor.param[1].type = "float"; m.source[0].technique_common.accessor.param[2].name = "Z"; m.source[0].technique_common.accessor.param[2].type = "float"; m.source[1].id = CreateId(); fa = new float_array(); fa.id = CreateId(); fa.Values = ToDoubleArray(mesh.normals); fa.count = (ulong)fa.Values.Length; m.source[1].Item = fa; m.source[1].technique_common = new sourceTechnique_common(); m.source[1].technique_common.accessor = new accessor(); m.source[1].technique_common.accessor.count = fa.count / 3; m.source[1].technique_common.accessor.source = "#" + fa.id; m.source[1].technique_common.accessor.stride = 3; m.source[1].technique_common.accessor.param = new[] { new param(), new param(), new param() }; m.source[1].technique_common.accessor.param[0].name = "X"; m.source[1].technique_common.accessor.param[0].type = "float"; m.source[1].technique_common.accessor.param[1].name = "Y"; m.source[1].technique_common.accessor.param[1].type = "float"; m.source[1].technique_common.accessor.param[2].name = "Z"; m.source[1].technique_common.accessor.param[2].type = "float"; m.source[2].id = CreateId(); fa = new float_array(); fa.id = CreateId(); fa.Values = ToDoubleArray(mesh.uv); fa.count = (ulong)fa.Values.Length; m.source[2].Item = fa; m.source[2].technique_common = new sourceTechnique_common(); m.source[2].technique_common.accessor = new accessor(); m.source[2].technique_common.accessor.count = fa.count / 2; m.source[2].technique_common.accessor.source = "#" + fa.id; m.source[2].technique_common.accessor.stride = 2; m.source[2].technique_common.accessor.param = new[] { new param(), new param() }; m.source[2].technique_common.accessor.param[0].name = "X"; m.source[2].technique_common.accessor.param[0].type = "float"; m.source[2].technique_common.accessor.param[1].name = "Y"; m.source[2].technique_common.accessor.param[1].type = "float"; m.vertices = new vertices(); m.vertices.id = CreateId(); m.vertices.input = new InputLocal[] { new InputLocal(), // position }; m.vertices.input[0].semantic = "POSITION"; m.vertices.input[0].source = "#" + m.source[0].id; var submeshes = new List <object>(); for (int i = 0; i < mesh.subMeshCount; i++) { var triangles = new List <int>(); var stringWriter = new StringWriter(); var t = mesh.GetTriangles(i); triangles.AddRange(t); for (int j = 0; j < t.Length; j = j + 3) { // index for position, normal and texcoord stringWriter.Write("{0} ", t[j]); stringWriter.Write("{0} ", t[j]); stringWriter.Write("{0} ", t[j]); stringWriter.Write("{0} ", t[j + 1]); stringWriter.Write("{0} ", t[j + 1]); stringWriter.Write("{0} ", t[j + 1]); stringWriter.Write("{0} ", t[j + 2]); stringWriter.Write("{0} ", t[j + 2]); stringWriter.Write("{0} ", t[j + 2]); } var tris = new triangles(); tris.count = (ulong)(triangles.Count / 3); tris.material = materialNames[i]; tris.input = new InputLocalOffset[] { new InputLocalOffset(), new InputLocalOffset(), new InputLocalOffset() }; tris.input[0].offset = 0; tris.input[0].semantic = "VERTEX"; tris.input[0].source = "#" + m.vertices.id; tris.p = stringWriter.ToString(); tris.input[1].offset = 1; tris.input[1].semantic = "NORMAL"; tris.input[1].source = "#" + m.source[1].id; tris.input[2].offset = 2; tris.input[2].semantic = "TEXCOORD"; tris.input[2].source = "#" + m.source[2].id; tris.input[2].set = 0; submeshes.Add(tris); } m.Items = submeshes.ToArray(); meshLookup[mesh] = id; return(id); }
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); }
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); } }
polygons[^ 1].Add(geometry[i]);
public void Export(string filePath) { PalletProperties palletProperties = _palletSolution.Analysis.PalletProperties; COLLADA model = new COLLADA(); // asset model.asset = new asset() { created = DateTime.Now, modified = DateTime.Now }; model.asset.keywords = "StackBuilder Pallet Case"; model.asset.title = _palletSolution.Title; model.asset.unit = new assetUnit() { name = "millimeters", meter = 0.001 }; model.asset.up_axis = UpAxisType.Z_UP; library_images images = new library_images(); library_materials materials = new library_materials(); library_effects effects = new library_effects(); library_geometries geometries = new library_geometries(); library_nodes nodes = new library_nodes(); library_cameras cameras = new library_cameras(); library_animations animations = new library_animations(); library_visual_scenes scenes = new library_visual_scenes(); COLLADAScene colladaScene = new COLLADAScene(); model.Items = new Object[] { images, materials, effects, geometries, nodes, cameras, animations, scenes }; model.scene = colladaScene; // colors and materials List <effect> listEffects = new List <effect>(); List <material> listMaterials = new List <material>(); List <image> listImages = new List <image>(); // effects effect effectPallet; material materialPallet; CreateMaterial(palletProperties.Color, null, null, "Pallet", out effectPallet, out materialPallet); listEffects.Add(effectPallet); listMaterials.Add(materialPallet); Box box = new Box(0, _palletSolution.Analysis.BProperties); // build list of effects / materials / images uint faceIndex = 0; foreach (Face face in box.Faces) { // build texture image if any string textureName = null; if (face.HasBitmap) { textureName = string.Format("textureFace_{0}", faceIndex); string texturePath = System.IO.Path.Combine( System.IO.Path.GetDirectoryName(filePath) , textureName + ".jpg"); double dimX = 0.0, dimY = 0.0; switch (faceIndex) { case 0: dimX = box.Width; dimY = box.Height; break; case 1: dimX = box.Width; dimY = box.Height; break; case 2: dimX = box.Length; dimY = box.Height; break; case 3: dimX = box.Length; dimY = box.Height; break; case 4: dimX = box.Length; dimY = box.Width; break; case 5: dimX = box.Length; dimY = box.Width; break; default: break; } face.ExtractFaceBitmap(dimX, dimY, _bmpWidth, texturePath); // create image listImages.Add( new image() { id = textureName + ".jpg", name = textureName + ".jpg", Item = @".\" + textureName + @".jpg" } ); } material materialCase; effect effectCase; CreateMaterial(face.ColorFill, textureName, "0", string.Format("Case{0}", faceIndex), out effectCase, out materialCase); listEffects.Add(effectCase); listMaterials.Add(materialCase); ++faceIndex; } // add to image list images.image = listImages.ToArray(); // case lines material effect effectCaseLines; material materialCaseLines; CreateMaterial(Color.Black, null, null, "CaseLines", out effectCaseLines, out materialCaseLines); listEffects.Add(effectCaseLines); listMaterials.Add(materialCaseLines); effects.effect = listEffects.ToArray(); materials.material = listMaterials.ToArray(); // geometries geometry geomPallet = new geometry() { id = "palletGeometry", name = "palletGeometry" }; geometry geomCase = new geometry() { id = "caseGeometry", name = "caseGeometry" }; geometries.geometry = new geometry[] { geomPallet, geomCase }; // pallet mesh meshPallet = CreatePalletMesh(palletProperties); geomPallet.Item = meshPallet; // case mesh meshCase = CreateCaseMesh(_palletSolution.Analysis.BProperties as BoxProperties); geomCase.Item = meshCase; // library_animations animation animationMain = new animation() { id = "animationMain_ID", name = "animationMain" }; animations.animation = new animation[] { animationMain }; List <object> listAnimationSource = new List <object>(); // library_visual_scenes visual_scene mainScene = new visual_scene() { id = "MainScene", name = "MainScene" }; scenes.visual_scene = new visual_scene[] { mainScene }; List <node> sceneNodes = new List <node>(); sceneNodes.Add(new node() { id = "PalletNode", name = "PalletNode", instance_geometry = new instance_geometry[] { new instance_geometry() { url = "#palletGeometry", bind_material = new bind_material() { technique_common = new instance_material[] { new instance_material() { symbol = "materialPallet", target = string.Format("#{0}", materialPallet.id) } } } } } }); uint caseIndex = 0; foreach (ILayer layer in _palletSolution) { BoxLayer bLayer = layer as BoxLayer; if (null == bLayer) { continue; } foreach (BoxPosition bp in bLayer) { Vector3D translation = bp.Position; Vector3D rotations = bp.Transformation.Rotations; node caseNode = new node() { id = string.Format("CaseNode_{0}_ID", caseIndex), name = string.Format("CaseNode_{0}", caseIndex), ItemsElementName = new ItemsChoiceType2[] { ItemsChoiceType2.translate, ItemsChoiceType2.rotate, ItemsChoiceType2.rotate, ItemsChoiceType2.rotate }, Items = new object[] { new TargetableFloat3() { Values = new double[] { translation.X, translation.Y, translation.Z }, sid = "t", }, new rotate() { Values = new double[] { 1.0, 0.0, 0.0, rotations.X }, sid = "rx" }, new rotate() { Values = new double[] { 0.0, 1.0, 0.0, rotations.Y }, sid = "ry" }, new rotate() { Values = new double[] { 0.0, 0.0, 1.0, rotations.Z }, sid = "rz" } }, instance_geometry = new instance_geometry[] { new instance_geometry() { url = "#caseGeometry", bind_material = new bind_material() { technique_common = new instance_material[] { new instance_material() { symbol = "materialCase0", target = "#material_Case0_ID" }, new instance_material() { symbol = "materialCase1", target = "#material_Case1_ID" }, new instance_material() { symbol = "materialCase2", target = "#material_Case2_ID" }, new instance_material() { symbol = "materialCase3", target = "#material_Case3_ID" }, new instance_material() { symbol = "materialCase4", target = "#material_Case4_ID" }, new instance_material() { symbol = "materialCase5", target = "#material_Case5_ID" }, new instance_material() { symbol = "materialCaseLines", target = "#material_CaseLines_ID" } } } } } }; sceneNodes.Add(caseNode); // animations CreateAnimation(caseIndex, (uint)_palletSolution.CaseCount, listAnimationSource, bp); // increment case index ++caseIndex; } } // add nodes mainScene.node = sceneNodes.ToArray(); animationMain.Items = listAnimationSource.ToArray(); // library_cameras camera cameraCamera = new camera() { id = "Camera-Camera", name = "Camera-Camera" }; cameraOpticsTechnique_commonPerspective cameraPerspective = new cameraOpticsTechnique_commonPerspective() { znear = new TargetableFloat() { sid = "znear", Value = 1.0 }, zfar = new TargetableFloat() { sid = "zfar", Value = 10000.0 } }; cameraCamera.optics = new cameraOptics() { technique_common = new cameraOpticsTechnique_common() { Item = cameraPerspective } }; cameras.camera = new camera[] { cameraCamera }; // colladaScene colladaScene.instance_visual_scene = new InstanceWithExtra() { url = "#MainScene" }; model.Save(filePath); model.Save(System.IO.Path.ChangeExtension(filePath, "xml")); }
private static List <STGenericMesh> LoadMeshData(ColladaScene scene, Node node, geometry geom, library_materials materials, controller controller = null) { List <STGenericMesh> meshes = new List <STGenericMesh>(); mesh daeMesh = geom.Item as mesh; STGenericMesh mesh = new STGenericMesh(); mesh.Vertices = new List <STVertex>(); mesh.Name = geom.name; meshes.Add(mesh); 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); } } for (int v = 0; v < mesh.Vertices.Count; v++) { if (scene.Settings.FlipUVsVertical) { for (int i = 0; i < mesh.Vertices[v].TexCoords.Length; i++) { mesh.Vertices[v].TexCoords[i] = new Vector2(mesh.Vertices[v].TexCoords[i].X, 1 - mesh.Vertices[v].TexCoords[i].Y); } } mesh.Vertices[v].Position = Vector3.TransformPosition(mesh.Vertices[v].Position, node.Transform); mesh.Vertices[v].Normal = Vector3.TransformNormal(mesh.Vertices[v].Normal, node.Transform); } if (controller != null) { skin skin = controller.Item as skin; var bindMatrix = CreateBindMatrix(skin.bind_shape_matrix); Console.WriteLine($"bindMatrix {bindMatrix.ExtractScale()}"); bindMatrix = bindMatrix.ClearScale(); for (int v = 0; v < mesh.Vertices.Count; v++) { mesh.Vertices[v].Position = Vector3.TransformPosition(mesh.Vertices[v].Position, bindMatrix); mesh.Vertices[v].Normal = Vector3.TransformNormal(mesh.Vertices[v].Normal, bindMatrix); } } // meshes = STGenericMesh.SeperatePolygonGroups<STGenericMesh>(mesh); if (scene.Settings.RemoveDuplicateVerts) { // mesh.RemoveDuplicateVertices(); } return(meshes); }