//this function generates a fixed tube static spScene generate_simple_tube(ISimplygonSDK sdk) { const int vertex_count = 16; const int triangle_count = 24; const int corner_count = triangle_count * 3; //create a scene object spScene scene = sdk.CreateScene(); // triangles x 3 indices ( or 3 corners ) int[] corner_ids = { 0, 1, 4, 4, 1, 5, 5, 1, 6, 1, 2, 6, 6, 2, 3, 6, 3, 7, 7, 3, 0, 7, 0, 4, 4, 5, 8, 8, 5, 9, 9, 5, 10, 5, 6, 10, 10, 6, 7, 10, 7, 11, 11, 7, 4, 11, 4, 8, 8, 9, 12, 12, 9, 13, 13, 9, 14, 9, 10, 14, 14, 10, 11, 14, 11, 15, 15, 11, 8, 15, 8, 12 }; // vertices with values for the x, y and z coordinates. float[] vertex_coordinates = { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, -1.0f, -1.0f, 0.0f, -1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 15.0f, 1.0f, 1.0f, 15.0f, -1.0f, -1.0f, 15.0f, -1.0f, -1.0f, 15.0f, 1.0f, 1.0f, 20.0f, 1.0f, 1.0f, 20.0f, -1.0f, -1.0f, 20.0f, -1.0f, -1.0f, 20.0f, 1.0f, 1.0f, 35.0f, 1.0f, 1.0f, 35.0f, -1.0f, -1.0f, 35.0f, -1.0f, -1.0f, 35.0f, 1.0f }; spGeometryData geom = sdk.CreateGeometryData(); //add bone weights and ids to geometry data (per vertex) geom.AddBoneWeights(2); spRealArray coords = geom.GetCoords(); spRidArray vertex_ids = geom.GetVertexIds(); spRealArray BoneWeights = geom.GetBoneWeights(); spRidArray BoneIds = geom.GetBoneIds(); geom.SetVertexCount(vertex_count); geom.SetTriangleCount(triangle_count); //create the bone table spSceneBoneTable scn_bone_table = scene.GetBoneTable(); //create an array to store bone ids spRidArray bone_ids = sdk.CreateRidArray(); //create root bone for the scene spSceneBone root_bone = sdk.CreateSceneBone(); root_bone.SetName("root_bone"); //add the bone to the scene bone table and get a bone id int root_bone_id = scn_bone_table.AddBone(root_bone); //a bone_ids.AddItem(root_bone_id); spSceneBone parent_bone = root_bone; //create bones and populate the scene bone table for (uint bone_index = 1; bone_index < total_bone; bone_index++) { spSceneBone bone = sdk.CreateSceneBone(); bone.SetName("ChildBone"); spTransform3 boneTransform = sdk.CreateTransform3(); //SET UP BONE IN BIND POSE //translate the child bone to its corrent position relative to the parent bone boneTransform.AddTransformation(bone.GetRelativeTransform()); boneTransform.PreMultiply(); boneTransform.AddTranslation(0.0f, 17.5f, 0.0f); //store the relatvice transform bone.GetRelativeTransform().DeepCopy(boneTransform.GetMatrix()); //add bone to the scene bone table int bone_id = scn_bone_table.AddBone(bone); //link bone to parent bone parent_bone.AddChild(bone); bone_ids.AddItem(bone_id); parent_bone = bone; } float[] v = new float[3]; for (int i = 0; i < vertex_count; ++i) { v[0] = vertex_coordinates[i * 3]; v[1] = vertex_coordinates[i * 3 + 1]; v[2] = vertex_coordinates[i * 3 + 2]; coords.SetTuple(i, v); //real blend_val = real((rid(i)/rid(4)))/real(3); float blend_val = 0.5f; float blend1 = 1.0f - blend_val; float blend2 = blend_val; int bone_id_1 = 0; int bone_id_2 = 1; if (i < 4) { bone_id_2 = -1; blend2 = 0; blend1 = 1; } else if (i > 11) { bone_id_1 = -1; blend2 = 1; blend1 = 0; } blend1 *= blend1; blend2 *= blend2; //set the bone weights to perform skining BoneWeights.SetItem((i * 2) + 0, blend1); BoneWeights.SetItem((i * 2) + 1, blend2); //set the bone ids influencing the vertex. BoneIds.SetItem((i * 2) + 0, bone_id_1); BoneIds.SetItem((i * 2) + 1, bone_id_2); } for (int i = 0; i < corner_count; ++i) { vertex_ids.SetItem(i, corner_ids[i]); } //create a scene mesh spSceneMesh mesh = sdk.CreateSceneMesh(); mesh.SetGeometry(geom); mesh.SetName("mesh"); //get the root node of the scene and add the root_bone and mesh to the scene scene.GetRootNode().AddChild(mesh); scene.GetRootNode().AddChild(root_bone); return(scene); }
static bool run_remeshing_for_lod(ISimplygonSDK sdk, int lod_index, uint merge_distance) { string userProfileDirectory = System.Environment.GetEnvironmentVariable("USERPROFILE"); string assetRoot = userProfileDirectory + @"/Documents/SimplygonSDK/SourceCode/Assets/"; string tempRoot = @"../../../../../temp/"; string output_filename = string.Format(tempRoot + "wall_lod{0}_merge{1}.obj", lod_index + 1, merge_distance); string output_material_filename = string.Format(tempRoot + "wall_lod{0}_merge{1}.mtl", lod_index + 1, merge_distance); string output_diffuse_filename = string.Format(tempRoot + "wall_lod{0}_merge{1}_diffuse.png", lod_index + 1, merge_distance); string output_normals_filename = string.Format(tempRoot + "wall_lod{0}_merge{1}_normals.png", lod_index + 1, merge_distance); // Import source geometry spGeometryData geom; spMaterialTable materials; Console.WriteLine("Importing wavefront .obj file...\n"); { // Run import spWavefrontImporter importer = sdk.CreateWavefrontImporter(); importer.SetExtractGroups(false); // We only want one large geometry, no need to extract groups importer.SetImportFilePath(assetRoot + "wall.obj"); if (!importer.RunImport()) { Console.WriteLine("Could not open input test file"); return(false); } // Get the only geometry and the materials geom = importer.GetFirstGeometry(); materials = importer.GetMaterials(); } // Make a copy of the geometry, we need the original for texture casting later. // The remesher will replace the data of the geometry after it has processed it. spGeometryData red_geom = geom.NewCopy(true); // Create a Scene-object and a SceneMesh-object. // Place the red_geom into the SceneMesh, and then the SceneMesh as a child to the RootNode. spScene scene = sdk.CreateScene(); spSceneMesh mesh = sdk.CreateSceneMesh(); mesh.SetGeometry(red_geom); mesh.SetName(red_geom.GetName().GetText()); scene.GetRootNode().AddChild(mesh); spMappingImage mapping_image; // Remesh it Console.WriteLine("Running remesher...\n"); { spRemeshingProcessor remesher = sdk.CreateRemeshingProcessor(); // Set target on-screen size in pixels remesher.GetRemeshingSettings().SetOnScreenSize(lod_sizes[lod_index]); // Set the on-screen merge distance in pixels. Holes smaller than this will be sealed // and geometries closer to each other than this will be merged. remesher.GetRemeshingSettings().SetMergeDistance(merge_distance); // Disable the cutting plane remesher.GetRemeshingSettings().SetUseGroundPlane(false); // Set to generate mapping image for texture casting. remesher.GetMappingImageSettings().SetGenerateMappingImage(true); remesher.SetSceneRoot(scene.GetRootNode()); remesher.RemeshGeometry(); // Mapping image is needed later on for texture casting. mapping_image = remesher.GetMappingImage(); } spSceneMesh topmesh = Utils.SimplygonCast <spSceneMesh>(scene.GetRootNode().GetChild(0), false); // Cast diffuse texture and normal map data into a new material // Create new material table. spMaterialTable output_materials = sdk.CreateMaterialTable(); // Create new material for the table. spMaterial output_material = sdk.CreateMaterial(); output_materials.AddMaterial(output_material); // Cast diffuse texture data { // Cast the data using a color caster spColorCaster cast = sdk.CreateColorCaster(); cast.SetColorType(SimplygonSDK.SG_MATERIAL_CHANNEL_DIFFUSE); cast.SetSourceMaterials(materials); cast.SetMappingImage(mapping_image); // The mapping image we got from the remeshing process. cast.SetOutputChannels(3); // RGB, 3 channels! (1 would be for grey scale, and 4 would be for RGBA.) cast.SetOutputChannelBitDepth(8); // 8 bits per channel. So in this case we will have 24bit colors RGB. cast.SetDilation(10); // To avoid mip-map artifacts, the empty pixels on the map needs to be filled to a degree aswell. cast.SetOutputFilePath(output_diffuse_filename); // Where the texture map will be saved to file. cast.CastMaterials(); // Fetch! // set the material properties // Set the diffuse multiplier for the texture. 1 means it will not differ from original texture, // For example: 0 would ignore a specified color and 2 would make a color twice as pronounced as the others. output_material.SetDiffuseRed(1); output_material.SetDiffuseGreen(1); output_material.SetDiffuseBlue(1); // Set material to point to created texture filename. output_material.SetTexture(SimplygonSDK.SG_MATERIAL_CHANNEL_DIFFUSE, output_diffuse_filename); } // cast normal map texture data { // cast the data using a color caster spNormalCaster cast = sdk.CreateNormalCaster(); cast.SetSourceMaterials(materials); cast.SetMappingImage(mapping_image); cast.SetOutputChannels(3); // RGB, 3 channels! (But really the x, y and z values for the normal) cast.SetOutputChannelBitDepth(8); cast.SetDilation(10); cast.SetOutputFilePath(output_normals_filename); cast.CastMaterials(); // Set material to point to created texture filename. output_material.SetTexture(SimplygonSDK.SG_MATERIAL_CHANNEL_NORMALS, output_normals_filename); } // export the remeshed geometry to an OBJ file Console.WriteLine("Exporting wavefront .obj file...\n"); { spWavefrontExporter exporter = sdk.CreateWavefrontExporter(); exporter.SetExportFilePath(output_filename); exporter.SetSingleGeometry(topmesh.GetGeometry()); exporter.SetMaterials(output_materials); if (!exporter.RunExport()) { Console.WriteLine("Failed to write result"); return(false); } } return(true); }