-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathscenegraph.h
More file actions
executable file
·169 lines (136 loc) · 4.43 KB
/
scenegraph.h
File metadata and controls
executable file
·169 lines (136 loc) · 4.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#ifndef SCENEGRAPH_H
#define SCENEGRAPH_H
#include <vector>
#include <memory>
#include <stdexcept>
#if __GNUG__
# include <tr1/memory>
#endif
#include "matrix4.h"
#include "rigtform.h"
#include "glsupport.h" // for Noncopyable
#include "uniforms.h"
#include "geometry.h"
#include "asstcommon.h"
class SgNodeVisitor;
class SgNode : public std::tr1::enable_shared_from_this<SgNode>, Noncopyable {
public:
virtual bool accept(SgNodeVisitor& vistor) = 0;
virtual ~SgNode() {}
// Two nodes are equal if and only if they're the same, i.e.,
// having the same in memory address
bool operator == (const SgNode& other) const {
return this == &other;
}
bool operator != (const SgNode& other) const {
return !(*this == other);
}
protected:
SgNode() {}
};
//
// A transform node can have descendents nodes. It uses a
// rigid body transform to represent its frame with respect to
// the parent frame
//
class SgTransformNode : public SgNode {
public:
virtual bool accept(SgNodeVisitor& visitor);
virtual RigTForm getRbt() = 0;
void addChild(std::tr1::shared_ptr<SgNode> child);
void removeChild(std::tr1::shared_ptr<SgNode> child);
int getNumChildren() const {
return children_.size();
}
std::tr1::shared_ptr<SgNode> getChild(int i) {
return children_[i];
}
private:
std::vector<std::tr1::shared_ptr<SgNode> > children_;
};
//
// A shape node has no decendents, but can perform drawing. It can also
// provide an affine matrix to be used to modify its geometry.
//
class SgShapeNode : public SgNode {
public:
virtual bool accept(SgNodeVisitor& visitor);
virtual Matrix4 getAffineMatrix() = 0;
virtual void draw(const Uniforms& uniforms) = 0;
};
// Visitor class for the scene graph nodes. If any of the
// visit/postVisit functions return false, the traverse
// will be terminated.
class SgNodeVisitor {
public:
virtual bool visit(SgTransformNode& node) { return true; }
virtual bool visit(SgShapeNode& node) { return true; }
virtual bool postVisit(SgTransformNode& node) { return true; }
virtual bool postVisit(SgShapeNode& node) { return true; }
};
RigTForm getPathAccumRbt(
std::tr1::shared_ptr<SgTransformNode> source,
std::tr1::shared_ptr<SgTransformNode> destination,
int offsetFromDestination = 0);
//----------------------------------------------------
// Concrete scene graph node implementations follow
//----------------------------------------------------
// A SgRoot node is a Transform node with identity Rbt
class SgRootNode : public SgTransformNode {
public:
SgRootNode() {}
virtual RigTForm getRbt() {
return RigTForm();
}
};
// A SgRbtNode is a Transform node that wraps a RigTForm
class SgRbtNode : public SgTransformNode {
public:
SgRbtNode(const RigTForm& rbt = RigTForm())
: rbt_ (rbt) {}
virtual RigTForm getRbt() {
return rbt_;
}
void setRbt(const RigTForm& rbt) {
rbt_ = rbt;
}
private:
RigTForm rbt_;
};
class SgGeometryShapeNode : public SgShapeNode {
public:
std::tr1::shared_ptr<Geometry> geometry;
std::tr1::shared_ptr<Material> material;
Matrix4 affineMatrix;
SgGeometryShapeNode(std::tr1::shared_ptr<Geometry> _geometry,
std::tr1::shared_ptr<Material> _material,
const Cvec3& translation = Cvec3(0, 0, 0),
const Cvec3& eulerAngles = Cvec3(0, 0, 0),
const Cvec3& scales = Cvec3(1, 1, 1))
: geometry(_geometry)
, material(_material)
, affineMatrix(Matrix4::makeTranslation(translation) *
Matrix4::makeXRotation(eulerAngles[0]) *
Matrix4::makeYRotation(eulerAngles[1]) *
Matrix4::makeZRotation(eulerAngles[2]) *
Matrix4::makeScale(scales)) {}
virtual Matrix4 getAffineMatrix() {
return affineMatrix;
}
void setAffineMatrix(const Cvec3& translation = Cvec3(0, 0, 0),
const Cvec3& eulerAngles = Cvec3(0, 0, 0),
const Cvec3& scales = Cvec3(1, 1, 1)) {
affineMatrix = Matrix4::makeTranslation(translation) *
Matrix4::makeXRotation(eulerAngles[0]) *
Matrix4::makeYRotation(eulerAngles[1]) *
Matrix4::makeZRotation(eulerAngles[2]) *
Matrix4::makeScale(scales);
}
virtual void draw(const Uniforms& uniforms) {
if (g_overridingMaterial)
g_overridingMaterial->draw(*geometry, uniforms);
else
material->draw(*geometry, uniforms);
}
};
#endif