-
Notifications
You must be signed in to change notification settings - Fork 46
/
MD5ModelNode.cpp
148 lines (116 loc) · 3.71 KB
/
MD5ModelNode.cpp
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
#include "MD5ModelNode.h"
#include "ivolumetest.h"
#include "imodelcache.h"
#include "ishaders.h"
#include "iscenegraph.h"
#include <functional>
namespace md5
{
MD5ModelNode::MD5ModelNode(const MD5ModelPtr& model) :
_model(new MD5Model(*model)) // create a copy of the incoming model, we need our own instance
{
}
const model::IModel& MD5ModelNode::getIModel() const {
return *_model;
}
model::IModel& MD5ModelNode::getIModel() {
return *_model;
}
bool MD5ModelNode::hasModifiedScale()
{
return false; // not supported
}
Vector3 MD5ModelNode::getModelScale()
{
return Vector3(1, 1, 1); // not supported
}
MD5ModelNode::~MD5ModelNode()
{
}
void MD5ModelNode::setModel(const MD5ModelPtr& model) {
_model = model;
}
const MD5ModelPtr& MD5ModelNode::getModel() const {
return _model;
}
// Bounded implementation
const AABB& MD5ModelNode::localAABB() const {
return _model->localAABB();
}
std::string MD5ModelNode::name() const {
return _model->getFilename();
}
scene::INode::Type MD5ModelNode::getNodeType() const
{
return Type::Model;
}
void MD5ModelNode::testSelect(Selector& selector, SelectionTest& test) {
_model->testSelect(selector, test, localToWorld());
}
bool MD5ModelNode::getIntersection(const Ray& ray, Vector3& intersection)
{
return _model->getIntersection(ray, intersection, localToWorld());
}
bool MD5ModelNode::intersectsLight(const RendererLight& light) const
{
return light.intersectsAABB(worldAABB());
}
void MD5ModelNode::renderSolid(RenderableCollector& collector, const VolumeTest& volume) const
{
assert(_renderEntity);
render(collector, volume, localToWorld(), *_renderEntity);
}
void MD5ModelNode::renderWireframe(RenderableCollector& collector, const VolumeTest& volume) const
{
assert(_renderEntity);
render(collector, volume, localToWorld(), *_renderEntity);
}
void MD5ModelNode::setRenderSystem(const RenderSystemPtr& renderSystem)
{
Node::setRenderSystem(renderSystem);
_model->setRenderSystem(renderSystem);
}
void MD5ModelNode::render(RenderableCollector& collector, const VolumeTest& volume,
const Matrix4& localToWorld, const IRenderEntity& entity) const
{
// Do some rough culling (per model, not per surface)
if (volume.TestAABB(localAABB(), localToWorld) == VOLUME_OUTSIDE)
{
return;
}
// greebo: Iterate over all MD5 surfaces and render them
for (auto i = _model->begin(); i != _model->end(); ++i)
{
assert(i->shader);
// Get the Material to test the shader name against the filter system
const MaterialPtr& surfaceShader = i->shader->getMaterial();
if (surfaceShader->isVisible())
{
assert(i->shader); // shader must be captured at this point
collector.addRenderable(
collector.supportsFullMaterials() ? *i->shader
: *entity.getWireShader(),
*i->surface, localToWorld, this, &entity
);
}
}
// Uncomment to render the skeleton
//collector.SetState(entity.getWireShader(), RenderableCollector::eFullMaterials);
//collector.addRenderable(_model->getRenderableSkeleton(), localToWorld, entity);
}
// Returns the name of the currently active skin
std::string MD5ModelNode::getSkin() const {
return _skin;
}
void MD5ModelNode::skinChanged(const std::string& newSkinName)
{
// greebo: Store the new skin name locally
_skin = newSkinName;
// greebo: Acquire the ModelSkin reference from the SkinCache
// Note: This always returns a valid reference
ModelSkin& skin = GlobalModelSkinCache().capture(_skin);
_model->applySkin(skin);
// Refresh the scene
GlobalSceneGraph().sceneChanged();
}
} // namespace md5