SceneDataExample.cpp

<< Click to Display Table of Contents >>

Navigation:  Simplygon 7.1 examples >

SceneDataExample.cpp

///////////////////////////////////////////////////////////////////////////
//
//  System:    Simplygon
//  File:      SceneDataExample.cpp
//  Language:  C++
//
//  Copyright (c) 2015 Donya Labs AB. 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[] )
    {
    // init SDK
    InitExample();
    // Run the example code
    RunExample();
    // deinit SDK
    DeinitExample();
    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
    spMaterial diffuseRed = sg->CreateMaterial();
    diffuseRed->SetName("red_diffuse");
    diffuseRed->SetDiffuseColor(0.5,0.0,0.0);
    diffuseRed->SetAmbientColor(0.5,0.0,0.0);
    spMaterial specRed = sg->CreateMaterial();
    specRed->SetName("red_spec");
    specRed->SetSpecularColor(1.0,0.0,0.0);
    specRed->SetAmbientColor(1.0,0.0,0.0);
    specRed->SetDiffuseColor(0.0,0.0,0.0);
    //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;
    }