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
|
#include "StaticModelNode.h"
#include "StaticModelSurface.h"
#include "ishaders.h"
#include "iscenegraph.h"
#include "imap.h"
namespace model
{
StaticModelNode::StaticModelNode(const StaticModelPtr& picoModel) :
_model(new StaticModel(*picoModel)),
_name(picoModel->getFilename())
{
_model->signal_ShadersChanged().connect(sigc::mem_fun(*this, &StaticModelNode::onModelShadersChanged));
_model->signal_SurfaceScaleApplied().connect(sigc::mem_fun(*this, &StaticModelNode::onModelScaleApplied));
// Update the skin
skinChanged("");
}
void StaticModelNode::createRenderableSurfaces()
{
_model->foreachSurface([&](const StaticModelSurface& surface)
{
if (surface.getVertexArray().empty() || surface.getIndexArray().empty())
{
return; // don't handle empty surfaces
}
emplaceRenderableSurface(std::make_shared<RenderableModelSurface>(surface, _renderEntity, localToWorld()));
});
}
void StaticModelNode::onInsertIntoScene(scene::IMapRootNode& root)
{
_model->connectUndoSystem(root.getUndoSystem());
ModelNodeBase::onInsertIntoScene(root);
}
void StaticModelNode::onRemoveFromScene(scene::IMapRootNode& root)
{
_model->disconnectUndoSystem(root.getUndoSystem());
ModelNodeBase::onRemoveFromScene(root);
}
const IModel& StaticModelNode::getIModel() const
{
return *_model;
}
IModel& StaticModelNode::getIModel()
{
return *_model;
}
bool StaticModelNode::hasModifiedScale()
{
return _model->getScale() != Vector3(1, 1, 1);
}
Vector3 StaticModelNode::getModelScale()
{
return _model->getScale();
}
const AABB& StaticModelNode::localAABB() const {
return _model->localAABB();
}
// SelectionTestable implementation
void StaticModelNode::testSelect(Selector& selector, SelectionTest& test) {
_model->testSelect(selector, test, localToWorld());
}
std::string StaticModelNode::name() const {
return _model->getFilename();
}
const StaticModelPtr& StaticModelNode::getModel() const {
return _model;
}
void StaticModelNode::setModel(const StaticModelPtr& model) {
_model = model;
}
void StaticModelNode::setRenderSystem(const RenderSystemPtr& renderSystem)
{
ModelNodeBase::setRenderSystem(renderSystem);
// This will trigger onModelShadersChanged() to refresh the renderables
_model->setRenderSystem(renderSystem);
}
void StaticModelNode::onModelShadersChanged()
{
// Detach renderables on model shader change,
// they will be refreshed next time things are rendered
detachFromShaders();
}
// Traceable implementation
bool StaticModelNode::getIntersection(const Ray& ray, Vector3& intersection)
{
return _model->getIntersection(ray, intersection, localToWorld());
}
void StaticModelNode::skinChanged(const std::string& newSkinName)
{
// The new skin name is stored locally
_skin = newSkinName;
// greebo: Acquire the ModelSkin reference from the SkinCache (might return null)
// Applying the skin might trigger onModelShadersChanged()
_model->applySkin(GlobalModelSkinCache().findSkin(getSkin()));
// Refresh the scene (TODO: get rid of that)
GlobalSceneGraph().sceneChanged();
}
std::string StaticModelNode::getSkin() const
{
return !_skin.empty() ? _skin : _defaultSkin;
}
void StaticModelNode::setDefaultSkin(const std::string& defaultSkin)
{
_defaultSkin = defaultSkin;
}
void StaticModelNode::_onTransformationChanged()
{
// Always revert to our original state before evaluating
if (getTransformationType() & TransformationType::Scale)
{
_model->revertScale();
_model->evaluateScale(getScale());
}
else if (getTransformationType() == TransformationType::NoTransform)
{
// Transformation has been changed but no transform mode is set,
// so the reason we got here is a cancelTransform() call, revert everything
if (_model->revertScale())
{
// revertScale returned true, the scale has actually been modified
_model->evaluateScale(Vector3(1,1,1));
}
}
}
void StaticModelNode::_applyTransformation()
{
if (getTransformationType() & TransformationType::Scale)
{
_model->revertScale();
_model->evaluateScale(getScale());
_model->freezeScale();
}
}
void StaticModelNode::onModelScaleApplied()
{
queueRenderableUpdate();
}
} // namespace model
|