Beispiel #1
0
        static void bend_geometry(ISimplygonSDK sdk, spScene scene)
        {
            // The two bones that influence the vertices
            //spMatrix4x4 sp_bone1;

            spGeometryData geom = Utils.SimplygonCast <spSceneMesh>(scene.GetRootNode().GetChild(0)).GetGeometry();

            // get the bone weights field and ids
            spRealArray boneWeights = geom.GetBoneWeights();
            spRidArray  boneIds     = geom.GetBoneIds();

            // get the Coordinates field
            spRealArray Coords = geom.GetCoords();

            // now, transform all vertices' coordinates using the bones
            for (int v = 0; v < Coords.GetTupleCount(); ++v)
            {
                Vector3D vtx = new Vector3D(Coords.GetItem(v * 3 + 0), Coords.GetItem(v * 3 + 1), Coords.GetItem(v * 3 + 2));

                uint no = boneIds.GetItemCount();

                int bone_id_1 = boneIds.GetItem(v * 2 + 0);
                int bone_id_2 = boneIds.GetItem(v * 2 + 1);

                spSceneBone bone_1;
                spSceneBone bone_2;

                Matrix4x4 b1gtMat;
                Matrix4x4 b2gtMat;

                Vector3D vtx1 = new Vector3D(vtx);
                Vector3D vtx2 = new Vector3D(vtx);

                if (bone_id_1 != -1)
                {
                    bone_1 = scene.GetBoneTable().GetBone(bone_id_1);

                    //retrieve the global transform of the bone in bind space
                    spMatrix4x4 rootGlobalTransform = sdk.CreateMatrix4x4();
                    bone_1.EvaluateDefaultGlobalTransformation(rootGlobalTransform);

                    //apply transfrom to animate bone
                    spTransform3 bone1_transform = sdk.CreateTransform3();
                    bone1_transform.AddTransformation(rootGlobalTransform);
                    bone1_transform.AddRotation(GetRadFromDegrees(-30), 1, 0, 0);
                    rootGlobalTransform = bone1_transform.GetMatrix();

                    //apply transform
                    b1gtMat = GetMatrix4x4FromIMatrix(rootGlobalTransform);
                    vtx1    = b1gtMat.MultiplyPointVector(vtx);
                }

                if (bone_id_2 != -1)
                {
                    bone_2 = scene.GetBoneTable().GetBone(bone_id_2);

                    spMatrix4x4 boneGlobalTransform = sdk.CreateMatrix4x4();
                    bone_2.EvaluateDefaultGlobalTransformation(boneGlobalTransform);

                    spTransform3 bone2_transform = sdk.CreateTransform3();

                    //transform into bone2's local space and apply transform
                    bone2_transform.PreMultiply();
                    boneGlobalTransform.Invert();
                    bone2_transform.AddTransformation(boneGlobalTransform);
                    bone2_transform.AddRotation(GetRadFromDegrees(-30), 1, 0, 0);
                    bone2_transform.AddTranslation(0.0f, 17.5f, 0.0f);

                    //apply transform of the first bone
                    bone2_transform.AddRotation(GetRadFromDegrees(-30), 1, 0, 0);

                    //get the global transform matrix for the animation pose
                    boneGlobalTransform = bone2_transform.GetMatrix();
                    b2gtMat             = GetMatrix4x4FromIMatrix(boneGlobalTransform);

                    //apply transform to the vertex
                    vtx2 = b2gtMat.MultiplyPointVector(vtx);
                }

                //get the bone weights from the geometry data
                float blend1 = boneWeights.GetItem(v * 2 + 0);
                float blend2 = boneWeights.GetItem(v * 2 + 1);

                // normalize the blend
                float blend_scale = 1.0f / (blend1 + blend2);
                blend1 *= blend_scale;
                blend2 *= blend_scale;


                // do a linear blend
                vtx = vtx1 * blend1 + vtx2 * blend2;

                // store in coordinates
                Coords.SetItem(v * 3 + 0, vtx.x);
                Coords.SetItem(v * 3 + 1, vtx.y);
                Coords.SetItem(v * 3 + 2, vtx.z);
            }
        }
Beispiel #2
0
        private static void RunHighQualityReduction(ISimplygonSDK SDK, string writeTo)
        {
            const int vertex_count   = 12;
            const int triangle_count = 4;

            // 4 triangles x 3 indices ( or 3 corners )
            int[] corner_ids = { 0,  1, 2,
                                 3,  4, 5,
                                 6,  7, 8,
                                 9, 10, 11 };

            // 12 vertices with values for the x, y and z coordinates.
            float[] vertex_coordinates = { 0.0f, 0.0f, 0.0f,
                                           1.0f, 0.0f, 0.0f,
                                           1.0f, 1.0f, 0.0f,

                                           1.0f, 1.0f, 0.0f,
                                           0.0f, 1.0f, 0.0f,
                                           0.0f, 0.0f, 0.0f,

                                           1.0f, 0.0f, 0.0f,
                                           2.0f, 0.0f, 0.0f,
                                           2.0f, 1.0f, 0.0f,

                                           2.0f, 1.0f, 0.0f,
                                           1.0f, 1.0f, 0.0f,
                                           1.0f, 0.0f, 0.0f };

            spGeometryData g      = SDK.CreateGeometryData();
            spRealArray    coords = g.GetCoords();
            spRidArray     ids    = g.GetVertexIds();

            g.SetVertexCount(vertex_count);
            g.SetTriangleCount(triangle_count);
            for (int i = 0; i < vertex_count; ++i)
            {
                //coords.SetTuple(i, vertex_coordinates[i * 3]);
                //coords[i] = vertex_coordinates[i * 3];
                float[] v = { 0.0f, 0.0f, 0.0f };
                for (int j = 0; j < 3; ++j)
                {
                    v[j] = vertex_coordinates[i * 3 + j];
                }

                coords.SetTuple(i, v);
            }
            for (int i = 0; i < corner_ids.Length; ++i)
            {
                ids.SetItem(i, corner_ids[i]);
            }

            // Create the reduction-processor, and set which scene to reduce
            using (var reductionProcessor = SDK.CreateReductionProcessor())
            {
                spScene     scene    = SDK.CreateScene();
                spSceneNode root     = scene.GetRootNode();
                spSceneMesh meshNode = SDK.CreateSceneMesh();
                meshNode.SetGeometry(g);
                //auto meshTransform = meshNode->GetRelativeTransform();
                //meshTransform->SetToTranslationTransform(100, 0, 0);
                root.AddChild(meshNode);
                reductionProcessor.SetSceneRoot(root);


                ///////////////////////////////////////////////////////////////////////////////////////////////
                // SETTINGS - Most of these are set to the same value by default, but are set anyway for clarity

                // The reduction settings object contains settings pertaining to the actual decimation
                var reductionSettings = reductionProcessor.GetReductionSettings();
                reductionSettings.SetKeepSymmetry(true);                                                               //Try, when possible to reduce symmetrically
                reductionSettings.SetUseAutomaticSymmetryDetection(true);                                              //Auto-detect the symmetry plane, if one exists. Can, if required, be set manually instead.
                reductionSettings.SetUseHighQualityNormalCalculation(true);                                            //Drastically increases the quality of the LODs normals, at the cost of extra processing time.
                reductionSettings.SetReductionHeuristics((uint)ReductionHeuristics.SG_REDUCTIONHEURISTICS_CONSISTENT); //Choose between "fast" and "consistent" processing. Fast will look as good, but may cause inconsistent
                //triangle counts when comparing MaxDeviation targets to the corresponding percentage targets.

                // The reducer uses importance weights for all features to decide where and how to reduce.
                // These are advanced settings and should only be changed if you have some specific reduction requirement
                //reductionSettings.SetShadingImportance(2.f); //This would make the shading twice as important to the reducer as the other features./

                // The actual reduction triangle target are controlled by these settings
                reductionSettings.SetStopCondition((uint)StopCondition.SG_STOPCONDITION_EITHER_IS_REACHED); //The reduction stops when any of the targets below is reached
                reductionSettings.SetReductionRatio(0.5f);                                                  //Targets at 50% of the original triangle count
                reductionSettings.SetMaxDeviation(float.MaxValue);                                          //Targets when an error of the specified size has been reached. As set here it never happens.

                // The repair settings object contains settings to fix the geometries
                var repairSettings = reductionProcessor.GetRepairSettings();
                repairSettings.SetTjuncDist(0.0f); //Removes t-junctions with distance 0.0f
                repairSettings.SetWeldDist(0.0f);  //Welds overlapping vertices

                // The normal calculation settings deal with the normal-specific reduction settings
                var normalSettings = reductionProcessor.GetNormalCalculationSettings();
                normalSettings.SetReplaceNormals(false); //If true, this will turn off normal handling in the reducer and recalculate them all afterwards instead.
                //If false, the reducer will try to preserve the original normals as well as possible
                //normalSettings.SetHardEdgeAngle( 60.f ); //If the normals are recalculated, this sets the hard-edge angle./

                //END SETTINGS
                ///////////////////////////////////////////////////////////////////////////////////////////////

                // Run the actual processing. After this, the set geometry will have been reduced according to the settings
                reductionProcessor.RunProcessing();

                // For this reduction, the LOD will use the same material set as the original, and hence no further processing is required

                //Create an .obj exporter to save our result
                using (var objExporter = SDK.CreateWavefrontExporter())
                {
                    // Generate the output filenames
                    string      outputGeomFilename = writeTo + ".obj";
                    spSceneMesh topmesh            = Utils.SimplygonCast <spSceneMesh>(scene.GetRootNode().GetChild(0), false);


                    // Do the actual exporting
                    objExporter.SetExportFilePath(outputGeomFilename);
                    objExporter.SetSingleGeometry(topmesh.GetGeometry()); //This is the geometry we set as the processing geom of the reducer, retaining the materials in the original scene
                    objExporter.RunExport();

                    //Done! LOD created.
                }
            }
        }
Beispiel #3
0
        //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);
        }