/// <summary> /// Adds source data. /// </summary> /// <param name="mesh">Parent mesh element.</param> /// <param name="srcID">ID of new source.</param> /// <param name="paramNames">Parameters.</param> /// <param name="values">Values.</param> private void AddSource(ref _daeElement mesh, string srcID, string paramNames, ref List <float> values) { _daeElement src = mesh.add("source"); src.setAttribute("id", srcID); _daeElement fa = src.add("float_array"); fa.setAttribute("id", src.getAttribute("id") + "-array"); fa.setAttribute("count", values.Count.ToString()); fa.setCharData(FloatArrayToString(ref values)); _daeElement acc = src.add("technique_common accessor"); acc.setAttribute("source", MakeUriRef(fa.getAttribute("id"))); string[] _params = paramNames.Split(' '); acc.setAttribute("stride", _params.Length.ToString()); acc.setAttribute("count", (values.Count / _params.Length).ToString()); foreach (string param in _params) { _daeElement p = acc.add("param"); p.setAttribute("name", param); p.setAttribute("type", "float"); } }
private void AddVisualScene(ref _daeElement root, ref DFMesh dfMesh) { string geomId = "model" + dfMesh.ObjectId.ToString(); string sceneName = geomId + "-scene"; _daeElement visualSceneLib = root.add("library_visual_scenes"); _daeElement visualScene = visualSceneLib.add("visual_scene"); visualScene.setAttribute("id", sceneName); // Add <node> _daeElement node = visualScene.add("node"); node.setAttribute("id", geomId + "-node"); // Transform <node> based on up vector switch (this.upVector) { case UpVectors.X_UP: node.add("rotate").setCharData("0 0 1 -90"); break; case UpVectors.Y_UP: // No change required. This is how the geometry is in DFMesh. break; case UpVectors.Z_UP: node.add("rotate").setCharData("1 0 0 90"); break; } // Instantiate the <geometry> _daeElement instanceGeom = node.add("instance_geometry"); instanceGeom.setAttribute("url", MakeUriRef(geomId)); // Bind material parameters _daeElement techniqueCommon = instanceGeom.add("bind_material technique_common"); foreach (var subMesh in dfMesh.SubMeshes) { string materialName = MakeMaterialName(subMesh.TextureArchive, subMesh.TextureRecord); _daeElement instanceMaterial = techniqueCommon.add("instance_material"); instanceMaterial.setAttribute("symbol", materialName + "-material"); instanceMaterial.setAttribute("target", MakeUriRef(materialName + "-material")); _daeElement bindVertexInput = instanceMaterial.add("bind_vertex_input"); bindVertexInput.setAttribute("semantic", "uv0"); bindVertexInput.setAttribute("input_semantic", "TEXCOORD"); bindVertexInput.setAttribute("input_set", "0"); } // Add a <scene> root.add("scene instance_visual_scene").setAttribute("url", MakeUriRef(sceneName)); }
/// <summary> /// Adds input. /// </summary> /// <param name="triangles">Triangles element.</param> /// <param name="semantic">Semantic.</param> /// <param name="srcID">Source ID.</param> /// <param name="offset">Offset.</param> /// <returns>True if successful.</returns> private bool AddInput(ref _daeElement triangles, string semantic, string srcID, int offset) { _daeElement input = triangles.add("input"); input.setAttribute("semantic", semantic); input.setAttribute("offset", offset.ToString()); input.setAttribute("source", MakeUriRef(srcID)); if (semantic == "TEXCOORD") { input.setAttribute("set", "0"); } return(true); }
/// <summary> /// Adds visual effects for materials. /// </summary> /// <param name="root">Root element.</param> /// <param name="dfMesh">DFMesh.</param> /// <returns>True if successful.</returns> private bool AddEffects(ref _daeElement root, ref DFMesh dfMesh) { // Add <library_effects> _daeElement effectLib = root.add("library_effects"); // Add one effect per submesh foreach (var subMesh in dfMesh.SubMeshes) { // Compose strings string materialName = MakeMaterialName(subMesh.TextureArchive, subMesh.TextureRecord); string effectName = materialName + "-effect"; // Add <effect> and profile_COMMON _daeElement effect = effectLib.add("effect"); effect.setAttribute("id", effectName); _daeElement profile = effect.add("profile_COMMON"); // Add <surface> _daeElement newparam = profile.add("newparam"); newparam.setAttribute("sid", "surface"); _daeElement surface = newparam.add("surface"); surface.setAttribute("type", "2D"); surface.add("init_from").setCharData(materialName + "-image"); // Add <sampler2D> newparam = profile.add("newparam"); newparam.setAttribute("sid", "sampler"); _daeElement sampler = newparam.add("sampler2D"); sampler.add("source").setCharData("surface"); sampler.add("minfilter").setCharData("LINEAR_MIPMAP_LINEAR"); sampler.add("magfilter").setCharData("LINEAR"); // Add <technique> _daeElement technique = profile.add("technique"); technique.setAttribute("sid", "common"); _daeElement texture = technique.add("phong diffuse texture"); texture.setAttribute("texture", "sampler"); texture.setAttribute("texcoord", "uv0"); } return(true); }
/// <summary> /// Adds materials. /// </summary> /// <param name="root">Root element.</param> /// <param name="dfMesh">DFMesh.</param> /// <returns>True if successful.</returns> private bool AddMaterials(ref _daeElement root, ref DFMesh dfMesh) { // Add <library_materials> _daeElement materialLib = root.add("library_materials"); // Add one material per submesh foreach (var subMesh in dfMesh.SubMeshes) { // Add <material> string materialName = MakeMaterialName(subMesh.TextureArchive, subMesh.TextureRecord); _daeElement material = materialLib.add("material"); material.setAttribute("id", materialName + "-material"); material.add("instance_effect").setAttribute("url", MakeUriRef(materialName + "-effect")); } return(true); }
/// <summary> /// Exports texture images and add references to the dae file. /// </summary> /// <param name="root">Root element.</param> /// <param name="dfMesh">DFMesh.</param> /// <returns>True if successful.</returns> private bool AddImages(ref _daeElement root, ref DFMesh dfMesh) { // Create <library_images> _daeElement imageLib = root.add("library_images"); // Export all textures. foreach (var subMesh in dfMesh.SubMeshes) { // Construct string string materialName = MakeMaterialName(subMesh.TextureArchive, subMesh.TextureRecord); string inputFilename = TextureFile.IndexToFileName(subMesh.TextureArchive); string outputFilename = materialName + "." + imageFormat.ToString().ToLower(); // Export texture string outputPath = Path.Combine(modelOutputPath, imageOutputRelativePath); string outputFilePath = Path.Combine(outputPath, outputFilename); if (!File.Exists(outputFilePath)) { // Load texture file textureFile.Load( Path.Combine(arena2Path, inputFilename), FileUsage.UseDisk, true); // Export image Bitmap bm = textureFile.GetManagedBitmap( subMesh.TextureRecord, 0, false, true); bm.Save(outputFilePath, imageFormat); } // Add <image> string relativeOutputPath = Path.Combine(imageOutputRelativePath, outputFilename); relativeOutputPath = relativeOutputPath.Replace("\\", "/"); _daeElement image = imageLib.add("image"); image.setAttribute("id", materialName + "-image"); image.add("init_from").setCharData(relativeOutputPath); } return(true); }
/// <summary> /// Adds geometry elements. /// </summary> /// <param name="root">Root element.</param> /// <param name="dfMesh">DFMesh.</param> private void AddGeometry(ref _daeElement root, ref DFMesh dfMesh) { _daeElement geomLib = root.add("library_geometries"); _daeElement geom = geomLib.add("geometry"); string geomId = "model" + dfMesh.ObjectId.ToString(); geom.setAttribute("id", geomId); _daeElement mesh = geom.add("mesh"); // Get source vertex data List <float> posArray = new List <float>(dfMesh.TotalVertices * 3); List <float> normalArray = new List <float>(dfMesh.TotalVertices * 3); List <float> uvArray = new List <float>(dfMesh.TotalVertices * 2); foreach (var subMesh in dfMesh.SubMeshes) { // Get texture dimensions for this submesh string archivePath = Path.Combine(arena2Path, TextureFile.IndexToFileName(subMesh.TextureArchive)); System.Drawing.Size sz = TextureFile.QuickSize(archivePath, subMesh.TextureRecord); // Collect vertex information for every plane in this submesh foreach (var plane in subMesh.Planes) { foreach (var point in plane.Points) { // Add position data posArray.Add(point.X); posArray.Add(-point.Y); posArray.Add(-point.Z); // Add normal data normalArray.Add(point.NX); normalArray.Add(-point.NY); normalArray.Add(-point.NZ); // Add UV data uvArray.Add(point.U / (float)sz.Width); uvArray.Add(-(point.V / (float)sz.Height)); } } } // Add positions, normals, and texture coordinates AddSource(ref mesh, geomId + "-positions", "X Y Z", ref posArray); AddSource(ref mesh, geomId + "-normals", "X Y Z", ref normalArray); AddSource(ref mesh, geomId + "-uv", "S T", ref uvArray); // Add <vertices> element _daeElement vertices = mesh.add("vertices"); vertices.setAttribute("id", geomId + "-vertices"); _daeElement verticesInput = vertices.add("input"); verticesInput.setAttribute("semantic", "POSITION"); verticesInput.setAttribute("source", MakeUriRef(geomId + "-positions")); // Add triangle indices for each submesh uint vertexCount = 0; foreach (var subMesh in dfMesh.SubMeshes) { // Loop through all planes in this submesh List <uint> indexArray = new List <uint>(subMesh.TotalTriangles * (3 * 3)); foreach (var plane in subMesh.Planes) { // Every DFPlane is a triangle fan radiating from point 0 uint sharedPoint = vertexCount++; // Index remaining points. There are (plane.Points.Length - 2) triangles in every plane for (int tri = 0; tri < plane.Points.Length - 2; tri++) { // Position, Normal, UV index for shared point indexArray.Add(sharedPoint); indexArray.Add(sharedPoint); indexArray.Add(sharedPoint); // Position, Normal, UV index for vertexCount indexArray.Add(vertexCount); indexArray.Add(vertexCount); indexArray.Add(vertexCount); // Position, Normal, UV index for vertexCount + 1 indexArray.Add(vertexCount + 1); indexArray.Add(vertexCount + 1); indexArray.Add(vertexCount + 1); // Increment vertexCount to next point in fan vertexCount++; } // Increment vertexCount to start of next fan in vertex buffer vertexCount++; } // Add <triangle> string materialName = MakeMaterialName(subMesh.TextureArchive, subMesh.TextureRecord); _daeElement triangles = mesh.add("triangles"); triangles.setAttribute("count", (indexArray.Count / (3 * 3)).ToString()); triangles.setAttribute("material", materialName + "-material"); AddInput(ref triangles, "VERTEX", geomId + "-vertices", 0); AddInput(ref triangles, "NORMAL", geomId + "-normals", 1); AddInput(ref triangles, "TEXCOORD", geomId + "-uv", 2); // Add <p> _daeElement p = triangles.add("p"); p.setCharData(UIntArrayToString(ref indexArray)); } }