SLProject  4.2.000
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
AppDemoSceneFigure.cpp
Go to the documentation of this file.
1 /**
2  * \file AppDemoSceneFigure.cpp
3  * \brief Implementation for an SLScene inherited class
4  * \details For more info about App framework and the scene assembly see:
5  * https://cpvrlab.github.io/SLProject4/app-framework.html
6  * \date May 2024
7  * \authors Marcus Hudritsch, Marino von Wattenwyl
8  * \copyright http://opensource.org/licenses/GPL-3.0
9  * \remarks Please use clangformat to format the code. See more code style on
10  * https://github.com/cpvrlab/SLProject4/wiki/SLProject-Coding-Style
11 */
12 
13 #include <AppDemoSceneFigure.h>
14 #include <AppCommon.h>
15 #include <SLAssetLoader.h>
16 #include <SLLightSpot.h>
17 #include <SLBox.h>
18 #include <SLRectangle.h>
19 #include <SLSphere.h>
20 #include <SLCylinder.h>
21 
22 //-----------------------------------------------------------------------------
23 AppDemoSceneFigure::AppDemoSceneFigure() : SLScene("Hierarchical Figure Test")
24 {
25  info("Hierarchical scenegraph with multiple subgroups in the figure. "
26  "The goal is design a figure with hierarchical transforms containing only rotations and translations. "
27  "You can see the hierarchy better in the Scenegraph window. In there the nodes are white and the meshes yellow. "
28  "You can view the axis aligned bounding boxes with key B and the nodes origin and axis with key X.");
29 }
30 //-----------------------------------------------------------------------------
31 //! All assets the should be loaded in parallel must be registered in here.
33 {
34 }
35 //-----------------------------------------------------------------------------
36 //! After parallel loading of the assets the scene gets assembled in here.
38 {
39  // Create textures and materials
40  SLMaterial* m1 = new SLMaterial(am, "m1", SLCol4f::BLACK, SLCol4f::WHITE, 128, 0.2f, 0.8f, 1.5f);
41  SLMaterial* m2 = new SLMaterial(am, "m2", SLCol4f::WHITE * 0.3f, SLCol4f::WHITE, 128, 0.5f, 0.0f, 1.0f);
42 
43  SLuint res = 20;
44  SLMesh* rectangle = new SLRectangle(am, SLVec2f(-5, -5), SLVec2f(5, 5), res, res, "rectangle", m2);
45  SLNode* floorRect = new SLNode(rectangle);
46  floorRect->rotate(90, -1, 0, 0);
47  floorRect->translate(0, 0, -5.5f);
48 
49  SLCamera* cam1 = new SLCamera("Camera 1");
50  cam1->translation(-7, 2, 7);
51  cam1->lookAt(0, -2, 0);
52  cam1->focalDist(10);
53  cam1->setInitialState();
55  cam1->background().colors(SLCol4f(0.7f, 0.6f, 1.0f),
56  SLCol4f(0.1f, 0.4f, 0.8f));
57 
58  SLLightSpot* light1 = new SLLightSpot(am, this, 5, 0, 5, 0.5f);
59  light1->powers(0.2f, 0.9f, 0.9f);
60  light1->attenuation(1, 0, 0);
61 
62  SLNode* figure = BuildFigureGroup(am, this, m1, true);
63 
64  SLNode* scene = new SLNode("scene node");
65  this->root3D(scene);
66  scene->addChild(light1);
67  scene->addChild(cam1);
68  scene->addChild(floorRect);
69  scene->addChild(figure);
70 
71  sv->camera(cam1);
72 }
73 
74 //-----------------------------------------------------------------------------
75 //! Build a hierarchical figurine with arms and legs
77  SLScene* s,
78  SLMaterial* mat,
79  SLbool withAnimation)
80 {
81  SLNode* cyl;
82  SLuint res = 16;
83 
84  // Feet
85  SLNode* feet = new SLNode("feet group (T13,R6)");
86  feet->addMesh(new SLSphere(am, 0.2f, 16, 16, "ankle", mat));
87  SLNode* feetbox = new SLNode(new SLBox(am,
88  -0.2f,
89  -0.1f,
90  0.0f,
91  0.2f,
92  0.1f,
93  0.8f,
94  "foot mesh",
95  mat),
96  "feet (T14)");
97  feetbox->translate(0.0f, -0.25f, -0.15f, TS_object);
98  feet->addChild(feetbox);
99  feet->translate(0.0f, 0.0f, 1.6f, TS_object);
100  feet->rotate(-90.0f, 1.0f, 0.0f, 0.0f);
101 
102  // Assemble low leg
103  SLNode* leglow = new SLNode("low leg group (T11, R5)");
104  leglow->addMesh(new SLSphere(am, 0.3f, res, res, "knee mesh", mat));
105  cyl = new SLNode(new SLCylinder(am,
106  0.2f,
107  1.4f,
108  1,
109  res,
110  false,
111  false,
112  "shin mesh",
113  mat),
114  "shin (T12)");
115  cyl->translate(0.0f, 0.0f, 0.2f, TS_object);
116  leglow->addChild(cyl);
117  leglow->addChild(feet);
118  leglow->translate(0.0f, 0.0f, 1.27f, TS_object);
119  leglow->rotate(0, 1.0f, 0.0f, 0.0f);
120 
121  // Assemble leg
122  SLNode* leg = new SLNode("leg group");
123  leg->addMesh(new SLSphere(am, 0.4f, res, res, "hip joint mesh", mat));
124  cyl = new SLNode(new SLCylinder(am,
125  0.3f,
126  1.0f,
127  1,
128  res,
129  false,
130  false,
131  "thigh mesh",
132  mat),
133  "thigh (T10)");
134  cyl->translate(0.0f, 0.0f, 0.27f, TS_object);
135  leg->addChild(cyl);
136  leg->addChild(leglow);
137 
138  // Assemble left & right leg
139  SLNode* legLeft = new SLNode("left leg group (T8)");
140  legLeft->translate(-0.4f, 0.0f, 2.2f, TS_object);
141  legLeft->addChild(leg);
142  SLNode* legRight = new SLNode("right leg group (T9)");
143  legRight->translate(0.4f, 0.0f, 2.2f, TS_object);
144  legRight->addChild(leg->copyRec());
145 
146  // Assemble low arm
147  SLNode* armlow = new SLNode("low arm group (T6,R4)");
148  armlow->addMesh(new SLSphere(am, 0.2f, 16, 16, "elbow mesh", mat));
149  cyl = new SLNode(new SLCylinder(am, 0.15f, 1.0f, 1, res, true, false, "low arm mesh", mat), "low arm (T7)");
150  cyl->translate(0.0f, 0.0f, 0.14f, TS_object);
151  armlow->addChild(cyl);
152  armlow->translate(0.0f, 0.0f, 1.2f, TS_object);
153  armlow->rotate(45, -1.0f, 0.0f, 0.0f);
154 
155  // Assemble arm
156  SLNode* arm = new SLNode("arm group");
157  arm->addMesh(new SLSphere(am, 0.3f, 16, 16, "shoulder mesh", mat));
158  cyl = new SLNode(new SLCylinder(am, 0.2f, 1.0f, 1, res, false, false, "upper arm mesh", mat), "upper arm (T5)");
159  cyl->translate(0.0f, 0.0f, 0.2f, TS_object);
160  arm->addChild(cyl);
161  arm->addChild(armlow);
162 
163  // Assemble left & right arm
164  SLNode* armLeft = new SLNode("left arm group (T3,R2)");
165  armLeft->translate(-1.1f, 0.0f, 0.3f, TS_object);
166  armLeft->rotate(10, -1, 0, 0);
167  armLeft->addChild(arm);
168  SLNode* armRight = new SLNode("right arm group (T4,R3)");
169  armRight->translate(1.1f, 0.0f, 0.3f, TS_object);
170  armRight->rotate(-60, -1, 0, 0);
171  armRight->addChild(arm->copyRec());
172 
173  // Assemble head & neck
174  SLNode* head = new SLNode(new SLSphere(am, 0.5f, res, res, "head mesh", mat), "head (T1)");
175  head->translate(0.0f, 0.0f, -0.7f, TS_object);
176  SLSphere* eye = new SLSphere(am, 0.06f, res, res, "eye mesh", mat);
177  SLNode* eyeL = new SLNode(eye, SLVec3f(-0.15f, 0.48f, 0), "eyeL (T1.1)");
178  SLNode* eyeR = new SLNode(eye, SLVec3f(0.15f, 0.48f, 0), "eyeR (T1.2)");
179  head->addChild(eyeL);
180  head->addChild(eyeR);
181  SLNode* neck = new SLNode(new SLCylinder(am, 0.25f, 0.3f, 1, res, false, false, "neck mesh", mat), "neck (T2)");
182  neck->translate(0.0f, 0.0f, -0.3f, TS_object);
183 
184  // Assemble figure Left
185  SLNode* figure = new SLNode("figure group (R1)");
186  figure->addChild(new SLNode(new SLBox(am, -0.8f, -0.4f, 0.0f, 0.8f, 0.4f, 2.0f, "chest mesh", mat), "chest"));
187  figure->addChild(head);
188  figure->addChild(neck);
189  figure->addChild(armLeft);
190  figure->addChild(armRight);
191  figure->addChild(legLeft);
192  figure->addChild(legRight);
193  figure->rotate(90, 1, 0, 0);
194 
195  // Add animations for left leg
196  if (withAnimation)
197  {
198  legLeft = figure->findChild<SLNode>("left leg group (T8)");
199  legLeft->rotate(30, -1, 0, 0);
200  SLAnimation* anim = s->animManager().createNodeAnimation("figure animation", 2.0f, true, EC_inOutQuint, AL_pingPongLoop);
201  anim->createNodeAnimTrackForRotation(legLeft, 60, SLVec3f(1, 0, 0));
202 
203  SLNode* legLowLeft = legLeft->findChild<SLNode>("low leg group (T11, R5)");
204  anim->createNodeAnimTrackForRotation(legLowLeft, 40, SLVec3f(1, 0, 0));
205 
206  SLNode* feetLeft = legLeft->findChild<SLNode>("feet group (T13,R6)");
207  anim->createNodeAnimTrackForRotation(feetLeft, 40, SLVec3f(1, 0, 0));
208 
209  armLeft = figure->findChild<SLNode>("left arm group (T3,R2)");
210  armLeft->rotate(-45, -1, 0, 0);
211  anim->createNodeAnimTrackForRotation(armLeft, -60, SLVec3f(1, 0, 0));
212 
213  armRight = figure->findChild<SLNode>("right arm group (T4,R3)");
214  armRight->rotate(45, -1, 0, 0);
215  anim->createNodeAnimTrackForRotation(armRight, 60, SLVec3f(1, 0, 0));
216  }
217 
218  return figure;
219 }
220 //-----------------------------------------------------------------------------
The AppCommon class holds the top-level instances of the app-demo.
Class declaration for an SLScene inherited class.
unsigned int SLuint
Definition: SL.h:171
bool SLbool
Definition: SL.h:175
@ EC_inOutQuint
quintic easing in and then out
Definition: SLEnums.h:196
@ TS_object
Definition: SLEnums.h:210
@ AL_pingPongLoop
loop forward and backwards
Definition: SLEnums.h:171
SLVec2< SLfloat > SLVec2f
Definition: SLVec2.h:141
SLVec3< SLfloat > SLVec3f
Definition: SLVec3.h:318
SLVec4< SLfloat > SLCol4f
Definition: SLVec4.h:237
static SLDeviceRotation devRot
Mobile device rotation from IMU.
Definition: AppCommon.h:64
static SLDeviceLocation devLoc
Mobile device location from GPS.
Definition: AppCommon.h:65
static SLNode * BuildFigureGroup(SLAssetManager *am, SLScene *s, SLMaterial *mat, SLbool withAnimation)
Build a hierarchical figurine with arms and legs.
void registerAssetsToLoad(SLAssetLoader &al) override
All assets the should be loaded in parallel must be registered in here.
void assemble(SLAssetManager *am, SLSceneView *sv) override
After parallel loading of the assets the scene gets assembled in here.
SLAnimation * createNodeAnimation(SLfloat duration)
SLAnimation is the base container for all animation data.
Definition: SLAnimation.h:33
SLNodeAnimTrack * createNodeAnimTrackForRotation(SLNode *target, SLfloat angleDeg1, const SLVec3f &axis)
Toplevel holder of the assets meshes, materials, textures and shaders.
void colors(const SLCol4f &uniformColor)
Sets a uniform background color.
Axis aligned box mesh.
Definition: SLBox.h:31
Active or visible camera node class.
Definition: SLCamera.h:54
void devRotLoc(SLDeviceRotation *devRot, SLDeviceLocation *devLoc)
Definition: SLCamera.h:120
void focalDist(const SLfloat f)
Definition: SLCamera.h:116
SLBackground & background()
Definition: SLCamera.h:165
SLCylinder is creates sphere mesh based on its SLRevolver methods.
Definition: SLCylinder.h:27
void attenuation(const SLfloat kConstant, const SLfloat kLinear, const SLfloat kQuadratic)
Definition: SLLight.h:116
void powers(SLfloat ambiPow, SLfloat diffPow, SLfloat specPow, const SLCol4f &ambiDiffSpecCol=SLCol4f::WHITE)
Sets the ambient, diffuse and specular powers all with the same color.
Definition: SLLight.h:74
SLLightSpot class for a spot light source.
Definition: SLLightSpot.h:36
Defines a standard CG material with textures and a shader program.
Definition: SLMaterial.h:56
An SLMesh object is a triangulated mesh, drawn with one draw call.
Definition: SLMesh.h:134
SLNode represents a node in a hierarchical scene graph.
Definition: SLNode.h:147
void addChild(SLNode *child)
Definition: SLNode.cpp:207
void translation(const SLVec3f &pos, SLTransformSpace relativeTo=TS_parent)
Definition: SLNode.cpp:828
void rotate(const SLQuat4f &rot, SLTransformSpace relativeTo=TS_object)
Definition: SLNode.cpp:945
virtual SLNode * copyRec()
Definition: SLNode.cpp:572
T * findChild(const SLstring &name="", SLbool findRecursive=true)
Definition: SLNode.h:388
virtual void addMesh(SLMesh *mesh)
Definition: SLNode.cpp:157
void setInitialState()
Definition: SLNode.cpp:1084
void lookAt(SLfloat targetX, SLfloat targetY, SLfloat targetZ, SLfloat upX=0, SLfloat upY=1, SLfloat upZ=0, SLTransformSpace relativeTo=TS_world)
Definition: SLNode.h:652
void translate(const SLVec3f &vec, SLTransformSpace relativeTo=TS_object)
Definition: SLNode.cpp:906
SLRectangle creates a rectangular mesh with a certain resolution.
Definition: SLRectangle.h:29
The SLScene class represents the top level instance holding the scene structure.
Definition: SLScene.h:47
SLNode * root3D()
Definition: SLScene.h:99
friend class SLNode
Definition: SLScene.h:48
SLAnimManager & animManager()
Definition: SLScene.h:97
SLstring & info()
Definition: SLScene.h:102
SceneView class represents a dynamic real time 3D view onto the scene.
Definition: SLSceneView.h:69
void camera(SLCamera *camera)
Definition: SLSceneView.h:145
SLSphere creates a sphere mesh based on SLSpheric w. 180 deg polar angle.
Definition: SLSphere.h:33
static SLVec4 BLACK
Definition: SLVec4.h:213
static SLVec4 WHITE
Definition: SLVec4.h:215