Cross-Platform Game Programming with gameplay3d/Creating a Scene


Overview of the scene graph

edit

A scene graph is a data structure that defines the spatial (and often also logical) relationship of a graphical scene for efficient management and rendering of graphics data.

It is typically represented as a hierarchical structure, which contains a collection of nodes including a top-level "root" node, a number of parent nodes each of which can have any number of child nodes, and a set of leaf nodes each of which has no child nodes and which therefore serve together as the bottom layer of the tree.

In gameplay3d:

  • the scene graph is represented by the Scene class;
  • instances of the Node class can be attached to a scene object;
  • further instances of the Node class can be added as children of existing nodes; and
  • various other attachments (such as models, lights, cameras, physics objects) can be attached to any node; and
  • an operation performed on a parent node affects all of its children.
 
A schematic diagram of a gameplay3d scene graph

An example of creating a scene, adding two nodes and attaching a camera and a light programatically (i.e. not using a .scene file) is as follows. The example is taken from "CreateSceneSample.cpp" in the "sample-browser" project:

// In your game class's initialize() method

// Create a new empty scene.
_scene = Scene::create();

// Create the camera.
Camera* camera = Camera::createPerspective(45.0f, getAspectRatio(), 1.0f, 10.0f);
Node* cameraNode = _scene->addNode("camera");

// Attach the camera to a node. This determines the position of the camera.
cameraNode->setCamera(camera);

// Make this the active camera of the scene.
_scene->setActiveCamera(camera);
SAFE_RELEASE(camera);

// Move the camera to look at the origin.
cameraNode->translate(0, 1, 5);
cameraNode->rotateX(MATH_DEG_TO_RAD(-11.25f));

// Create a white light.
Light* light = Light::createDirectional(0.75f, 0.75f, 0.75f);
Node* lightNode = _scene->addNode("light");
lightNode->setLight(light);

// Release the light because the node now holds a reference to it.
SAFE_RELEASE(light);

// Rotate the camera downwards.
lightNode->rotateX(MATH_DEG_TO_RAD(-45.0f));

Generally, when making a game in gameplay3d:

  • you will begin by loading/building a large scene representing all the components needed in the game level. This is done once during Game::initialize();
  • during each call to the Game::update() method, your code will update changes to the nodes, and attached components, based on events such as user input;
  • during each call to the Game::render() method, your code will traverse the scene and render the parts in the scene that are visible from scene's active camera; and
  • on exit, the Game::finalize() method will be called, during which you will release any outstanding dynamically-allocated resources (see Cross-Platform Game Programming with gameplay3d/gameplay3d_Design_Concepts#Managing_shared_objects).

Nodes

edit

The following components can be attached to the gameplay::Node class:

Components which can be attached to the gameplay::Node class
Component Description
gameplay::Model Used to represent the mesh/geometry in the scene.
gameplay::Camera Used to represent a view/perspective into the scene.
gameplay::Light Used to hold lighting information that can affect how a Model is rendered.
gameplay::PhysicsCollisionObject Used to define the basic physics dynamics that will be simulated.
gameplay::ParticleEmitter Used to represent smoke, steam, fire and other atmospheric effects.
gameplay::Terrain Used to represent a height map based terrain.
gameplay::AudioSource Used to represent a source where audio is being played from.
gameplay::Form Used to represent a user interface that can be in a scene.

A note about order of transformations

edit

Models and meshes

edit

Lights

edit

Cameras

edit

Terrain

edit

Other node attachments

edit

Creating Scene Assets in Modeling Software

edit

You can use any modeling software capable of creating FBX files. Support for Collada files was removed in gameplay 2.0.0 owing to the relatively poor level of support for the format by some 3d modelling packages, but may be added back in future if adoption improves.

Creating Scene Assets with Maya

edit

Creating Scene Assets with Blender

edit

Blender can export FBX (and Collada) files. We recommend using at least version 2.70. The upcoming version 2.71 has an improved FBX export capability including tangents and binormals.

Exporting an FBX file

edit

Blender has a built in FBX exporter. Version 2.70 works. Do take note of these two important notes, particularly if you have animations:

  • Blender and Gameplay have a different up axis. When exporting FBX file, select the up axis to be Y axis and the forward axis to be Z axis. Without this animation will be totally distorted
  • The FBX exporter can create empty animation channel. You have to use the -oa option to transform the file for gameplay

Encoding your asset to .GPB

edit

Now that your model has been exported to a known format, there is one more step to complete in order to get it ready for use. Your model needs to be converted from the exported interchange format .FBX into an efficient binary bundle format that the gameplay framework can use. To do this run gameplay-encoder with the required parameters.

Encoding from FBX (.FBX)

edit

To encode your FBX scene file(.fbx) into the gameplay binary format (.gpb), run the following command:

gameplay-encoder -oa -g HIKCharacterNode_boy_Reference animations "../../gameplay-samples/sample-character/res/boy.fbx"

Let's take a look at some of the extra parameters passed into the encoder.

The -g parameter says that you want to group all animations on HIKCharacterNode_boy_reference, and its children node into an animation called 'animations'. The -oa option says that you want optimize the animations. This is important if you import complex file from Blender as it otherwise may lead to unreadable files due to empty animation channels.

This encoding is necessary because the FBX, or, in the case of fonts, TrueType files are really just interchange formats, and are huge ascii files that are not recommended for runtime format. Encoding them packs them into a more efficient binary bundle and only takes the data that is needed by the gameplay framework.

Working with .scene files

edit

In order to assemble a scene in gameplay3d using a .scene file, there are two main steps:

  • create a .scene text file describing your scene; and
  • load the scene in your game code by calling the Scene::load() static method.

Creating your .scene file

edit

Loading the scene in your game code

edit

The scene file can be loaded into your game as follows:

// Load the scene
_scene = Scene::load("res/myscene.scene");