<< 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;
}