This is part of the ChasmIntro series.
The second introduction to Chasm deals with creating a world in SVE where the user points at an object, pushes a button and the object moves to a new location.
This section demonstrates how to solve a simple 3D interaction problem inside Chasm. The description of the problem is this: When the user selects the end object out of a line of objects with raycasting, have that object move to the center and above the other objects.
Go to the directory chasm/tutorials/tut2_move_object where you will find a Makefile, the tutorial2_base.C file and the directory answers which contains finished versions of the code. There are also files for SVE such as sve.init, termio.h and tut2.world.
Go through the following steps. Use the help button "?" as needed. Some of the descriptions are purposefully vague. If you become stuck, see the answers directory.
chasm2C -s Scenario_MoveObject
chasm2C -s Scenario_MoveObject
Notice how it warns you that the Scenario_MoveObject_sup.h and .C and .h files exist. Chasm makes sure you do not overwrite your code files.
#include "Scenario_MoveObject.chasm.h"
Notice this uses the .chasm.h version and not the .h version. The .chasm.h version (which you have not created yet) has had a preprocessing command (chasmprocess) run over the Scenario_MoveObject's .h and .C file using the information in the .chasmxml file to create the .chasm.h and .chasm.C files. These files hold information from the user's code and the Chasm structure and are overwritten constantly so do not modify them directly. Only modify the .C, .h and _sup.h files.
Scenario_MoveObject.chasm* scenario = NULL;
and before Chasm_InteractiveShell() function call, add the call to the static constructor:
scenario = Scenario_MoveObject::cScenario_MoveObject(
raycasting, testcube[NUMCUBES-1]);
testcube is a WorldObject and wand and raycasting are the passed in Concepts to Scenario_MoveObject.
Button* button; Raycasting* raycasting; WorldObject *wand,*ray;
and create instances of them:
wand = WorldObject::cWorldObject("wand",
new WorldObjectBuilderSVE(
SVE_loadObject("wand.obj","wand")));
SVE_attachToObject(SVE_findWorldObject("wand"),
SVE_findWorldObject("SVE hand") );
ray = WorldObject::cWorldObject("ray",
new WorldObjectBuilderSVE(
SVE_loadObject("ray.obj","ray"),
SVE_findWorldObject("SVE cursor")));
button = Button::cButton(new ButtonBuilderSVE(1));
raycasting = RaycastingSelection::cRaycastingSelection(10.,
s_selection,selectable,ray,
new RaycastingSelectionBuilderSVE());
CHASM::WHEN_state_THEN_symbol(raycasting,button->down,
raycasting->rechecking);
Much of this complexity deals with SVE calls and creating the SVE builders.
Button* button; ... button = Button::cButton(new ButtonBuilderSVE(1));
Notice how Builders are used in the Concepts. Read about builders here. They allow the same concept to be implemented in different toolkits by abstracting their functionality in Chasm structures.
make
./tutorial2
Err: Scenario_MoveObject.C line(134) in builderInitialization: ERROR: you did not set Component variable 'mfs' in Scenario_MoveObject_1
We have to implement the Component concepts in Scenario_MoveObject.
setComponent("mfs",
mfs = MonitorObjectForSelection::cMonitorObjectForSelection(
_targetedobject,_raycasting));
setComponent("apt",
apt = AnimatedPositionTranslation::cAnimatedPositionTranslation(
-0.8,0.4,0.,5.,
_targetedobject->pointAtPosition()));
Notice you do not need to include header files as this is done automatically for you. These components are created here because you told Chasm that the Concept was responsible for them by setting the CIF to created.
Also notice how "mfs" and "apt" are the names of the components you set using the Chasm GUI.
To move the user head to a good position type: s 0 1.8 0 0 0 0
To move the hand, type:
t 2
s 0. 1.5 -.5 28. 0. 0.
Use the 'fly' command to move the wand and shift arrow keys to change the angle of the ray. When you are pointing at the last object (as per the image above), click the button using the command: b 1