Show / Hide Table of Contents
    ///////////////////////////////////////////////////////////////////////////
    //
    //  System:    Simplygon
    //  File:      SceneDataExample.cpp
    //  Language:  C++
    //
    //  Copyright (c) 2019 Microsoft. All rights reserved.
    //
    ///////////////////////////////////////////////////////////////////////////
    //
    //  #Description# This example shows how to use the simplygon scene data.
    //  First we create a scene. We fetch the scene's material table and add
    //  a red diffuse and a red specular material. We then create two cube geometries
    //  with one assigned the diffuse material and the other the specular material.
    //  Two scene mesh nodes are created that refer to the cubes. The scene meshes
    //  are then added to the scene's root node as children.
    //
    ///////////////////////////////////////////////////////////////////////////
    
    #include "../Common/Example.h"
    #include "../Common/Vector3D.h"
    #include "../Common/Matrix4x4.h"
    
    
    
    /////////////////////////////////////////////////////////////////////
    // Main function with startup and shutdown code
    
    void RunExample();
    void save_scene_to_file( spScene scene, const std::string& obj_filepath, const std::string& mat_filepath );
    spGeometryData generate_cube( rid matId );
    
    
    
    int main( int argc, char* argv[] )
        {
        try
        {
            // init SDK
            InitExample();
    
            // Run the example code
            RunExample();
    
            // deinit SDK
            DeinitExample();
        }
        catch (const std::exception& ex)
        {
            std::cerr << ex.what() << std::endl;
            return -1;
        }
    
        return 0;
        }
    
    // This function runs the example by creating a simplygon scene and generating
    // two materials. The materials are stored in the scene's material table.
    // Two cubes are generated which refer to the materials created earlier.
    // Two scene mesh nodes are created which refer to the cube geometries created
    // earlier. One of the scene meshes is transformed using the transform3 class.
    // Finally the scene meshes are added as children to the root node of the scene
    // and exported to a wavefront file along with corresponding material file.
    void RunExample()
        {
        //create a simplygon scene
        spScene scene = sg->CreateScene();
    
        //get material table from the scene
        spMaterialTable matTable = scene->GetMaterialTable();
    
        //create a red diffuse material and a red specular material
        spShadingColorNode redNode = sg->CreateShadingColorNode();
        redNode->SetColor( 0.5f, 0.f, 0.f, 0.f );
    
        spMaterial diffuseRed = sg->CreateMaterial();
        diffuseRed->SetName( "red_diffuse" );
        diffuseRed->SetShadingNetwork( SG_MATERIAL_CHANNEL_DIFFUSE, redNode );
        diffuseRed->SetShadingNetwork( SG_MATERIAL_CHANNEL_AMBIENT, redNode );
    
        spMaterial specRed = sg->CreateMaterial();
        specRed->SetName( "red_spec" );
        specRed->SetShadingNetwork( SG_MATERIAL_CHANNEL_DIFFUSE, redNode );
        specRed->SetShadingNetwork( SG_MATERIAL_CHANNEL_SPECULAR, redNode );
    
        //add the materials to the material table
        rid d_mat_id = matTable->AddMaterial( diffuseRed );
        rid s_mat_id = matTable->AddMaterial( specRed );
    
        //create two scene mesh objects
        spSceneMesh cube_one = sg->CreateSceneMesh();
        spSceneMesh cube_two = sg->CreateSceneMesh();
    
        //set name on the scene meshes
        cube_one->SetName( "cube_one" );
        cube_one->SetOriginalName( "cube_one" );
        cube_two->SetName( "cube_two" );
        cube_two->SetOriginalName( "cube_two" );
    
        cube_one->SetGeometry( generate_cube( s_mat_id ) );
        cube_two->SetGeometry( generate_cube( d_mat_id ) );
    
        //add the two scene meshes as child to the root node of the scene
        scene->GetRootNode()->AddChild( cube_one );
        scene->GetRootNode()->AddChild( cube_two );
    
        //create a transform node
        spTransform3 xform = sg->CreateTransform3();
    
        //set the transform to use premultiply
        xform->PreMultiply();
    
        //add rotations and translations
        xform->AddRotation( GetRadFromDegrees( 45 ), 0, 1, 0 );
        xform->AddRotation( GetRadFromDegrees( 45 ), 1, 0, 0 );
        xform->AddTranslation( 0, 5.0, 0.0 );
    
        //access the node for cube_two in the scene
        spSceneMesh node = Cast<ISceneMesh>( scene->GetNodeFromPath( "Root/cube_two" ) );
    
        //apply transformation on the node
        node->GetRelativeTransform()->DeepCopy( xform->GetMatrix() );
    
        std::string outputObjPath = GetExecutablePath() + "cubes.obj";
        std::string outputMtlPath = GetExecutablePath() + "cubes.mtl";
    
        //store the scene and material to file
        save_scene_to_file( scene, outputObjPath, outputMtlPath );
    
        }
    
    
    // This function stores the data into an .obj file and materials in .mtl file
    void save_scene_to_file( spScene scene, const std::string& filepath, const std::string& mat_filepath )
        {
        // create the wavefront exporter
        spWavefrontExporter exp = sg->CreateWavefrontExporter();
    
        // set the geometries
        exp->SetScene( scene );
    
        // set file paths
        exp->SetExportFilePath( filepath.c_str() );
        exp->SetMaterialFilePath( mat_filepath.c_str() );
    
        // export to file
        exp->RunExport();
        }
    
    
    //this function generates a fixed cube
    spGeometryData generate_cube( rid matId )
        {
        const int vertex_count = 8;
        const int triangle_count = 12;
        const int corner_count = triangle_count * 3;
    
        // 4 triangles x 3 indices ( or 3 corners )
        int corner_ids[corner_count * 1] = { 0, 1, 4,
            4, 1, 5,
            5, 1, 6,
            1, 2, 6,
            6, 2, 3,
            6, 3, 7,
            7, 3, 0,
            7, 0, 4,
            0, 2, 1,
            0, 3, 2,
            4, 5, 6,
            4, 6, 7 };
    
        // 12 vertices with values for the x, y and z coordinates.
        float vertex_coordinates[vertex_count * 3] = { 1.0,  -1.0,  1.0,
            1.0,  -1.0,  -1.0,
            -1.0,  -1.0,  -1.0,
            -1.0,  -1.0,  1.0,
    
            1.0,  1.0,  1.0,
            1.0,  1.0,  -1.0,
            -1.0,  1.0,  -1.0,
            -1.0,  1.0,  1.0 };
    
        spGeometryData geom = sg->CreateGeometryData();
    
        //add material data
        //materials are assigned per triangle
        geom->AddMaterialIds();
    
    
        spRealArray coords = geom->GetCoords();
        spRidArray vertex_ids = geom->GetVertexIds();
        spRidArray matIds = geom->GetMaterialIds();
    
        geom->SetVertexCount( vertex_count );
        geom->SetTriangleCount( triangle_count );
    
    
        for( int i = 0; i < vertex_count; ++i )
            {
            coords->SetTuple( i, &vertex_coordinates[i * 3] );
            }
    
        for( int i = 0; i < corner_count; ++i )
            {
            vertex_ids->SetItem( i, corner_ids[i] );
            }
    
        //loop through all the triangles an assign material
        for( int i = 0; i < triangle_count; ++i )
            {
            matIds->SetItem( i, matId );
            }
    
    
        return geom;
        }
    
    Back to top Terms of Use | Privacy and cookies | Trademarks | Copyright © 2019 Microsoft