-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscenegraph.h
157 lines (126 loc) · 3.94 KB
/
scenegraph.h
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
#ifndef SCENEGRAPH_H
#define SCENEGRAPH_H
#include <vector>
#include <memory>
#include <stdexcept>
#if __GNUG__
# include <tr1/memory>
#endif
#include "cvec.h"
#include "matrix4.h"
#include "rigtform.h"
#include "glsupport.h" // for Noncopyable
#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 ShaderState& curSS) = 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_;
};
// A SgGeometryShapeNode is a Shape node that wraps a user geometry class
template<typename Geometry>
class SgGeometryShapeNode : public SgShapeNode {
std::tr1::shared_ptr<Geometry> geometry_;
Matrix4 affineMatrix_;
Cvec3 color_;
public:
SgGeometryShapeNode(std::tr1::shared_ptr<Geometry> geometry,
const Cvec3& color,
const Cvec3& translation = Cvec3(0, 0, 0),
const Cvec3& eulerAngles = Cvec3(0, 0, 0),
const Cvec3& scales = Cvec3(1, 1, 1))
: geometry_(geometry)
, color_(color)
, affineMatrix_(Matrix4::makeTranslation(translation) *
Matrix4::makeXRotation(eulerAngles[0]) *
Matrix4::makeYRotation(eulerAngles[1]) *
Matrix4::makeZRotation(eulerAngles[2]) *
Matrix4::makeScale(scales)) {}
virtual Matrix4 getAffineMatrix() {
return affineMatrix_;
}
virtual void draw(const ShaderState& curSS) {
safe_glUniform3f(curSS.h_uColor, color_[0], color_[1], color_[2]);
geometry_->draw(curSS);
}
};
#endif