Skip to content

Commit

Permalink
#5584: MD5 models attach RenderableModelSurfaces to the shaders now
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed Jan 16, 2022
1 parent fdae71a commit 4336484
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 20 deletions.
112 changes: 93 additions & 19 deletions radiantcore/model/md5/MD5ModelNode.cpp
Expand Up @@ -10,15 +10,17 @@ namespace md5
{

MD5ModelNode::MD5ModelNode(const MD5ModelPtr& model) :
_model(new MD5Model(*model)) // create a copy of the incoming model, we need our own instance
{
}
_model(new MD5Model(*model)), // create a copy of the incoming model, we need our own instance
_attachedToShaders(false)
{}

const model::IModel& MD5ModelNode::getIModel() const {
const model::IModel& MD5ModelNode::getIModel() const
{
return *_model;
}

model::IModel& MD5ModelNode::getIModel() {
model::IModel& MD5ModelNode::getIModel()
{
return *_model;
}

Expand All @@ -32,24 +34,24 @@ Vector3 MD5ModelNode::getModelScale()
return Vector3(1, 1, 1); // not supported
}

MD5ModelNode::~MD5ModelNode()
void MD5ModelNode::setModel(const MD5ModelPtr& model)
{
}

void MD5ModelNode::setModel(const MD5ModelPtr& model) {
_model = model;
}

const MD5ModelPtr& MD5ModelNode::getModel() const {
const MD5ModelPtr& MD5ModelNode::getModel() const
{
return _model;
}

// Bounded implementation
const AABB& MD5ModelNode::localAABB() const {
const AABB& MD5ModelNode::localAABB() const
{
return _model->localAABB();
}

std::string MD5ModelNode::name() const {
std::string MD5ModelNode::name() const
{
return _model->getFilename();
}

Expand Down Expand Up @@ -78,7 +80,8 @@ void MD5ModelNode::onRemoveFromScene(scene::IMapRootNode& root)
_renderableSurfaces.clear();
}

void MD5ModelNode::testSelect(Selector& selector, SelectionTest& test) {
void MD5ModelNode::testSelect(Selector& selector, SelectionTest& test)
{
_model->testSelect(selector, test, localToWorld());
}

Expand All @@ -87,36 +90,92 @@ bool MD5ModelNode::getIntersection(const Ray& ray, Vector3& intersection)
return _model->getIntersection(ray, intersection, localToWorld());
}

void MD5ModelNode::renderSolid(IRenderableCollector& collector, const VolumeTest& volume) const
void MD5ModelNode::onPreRender(const VolumeTest& volume)
{
assert(_renderEntity);

// Attach renderables (or do nothing if everything is up to date)
attachToShaders();
}

void MD5ModelNode::renderSolid(IRenderableCollector& collector, const VolumeTest& volume) const
{
assert(_renderEntity);
#if 0
render(collector, volume, localToWorld(), *_renderEntity);
#endif
}

void MD5ModelNode::renderWireframe(IRenderableCollector& collector, const VolumeTest& volume) const
{
assert(_renderEntity);

#if 0
render(collector, volume, localToWorld(), *_renderEntity);
#endif
}

void MD5ModelNode::renderHighlights(IRenderableCollector& collector, const VolumeTest& volume)
{
#if 0
render(collector, volume, localToWorld(), *_renderEntity);
#endif
auto identity = Matrix4::getIdentity();

for (const auto& surface : _renderableSurfaces)
{
collector.addHighlightRenderable(*surface, identity);
}
}

void MD5ModelNode::setRenderSystem(const RenderSystemPtr& renderSystem)
{
Node::setRenderSystem(renderSystem);

// Detach renderables on render system change
detachFromShaders();

_model->setRenderSystem(renderSystem);
}

void MD5ModelNode::detachFromShaders()
{
// Detach any existing surfaces. In case we need them again,
// the node will re-attach in the next pre-render phase
for (auto& surface : _renderableSurfaces)
{
surface->clear();
}

_attachedToShaders = false;
}

void MD5ModelNode::attachToShaders()
{
if (_attachedToShaders) return;

auto renderSystem = _renderSystem.lock();

if (!renderSystem) return;

for (auto& surface : _renderableSurfaces)
{
auto shader = renderSystem->capture(surface->getSurface().getActiveMaterial());
surface->attachToShader(shader);

// For orthoview rendering we need the entity's wireframe shader
if (_renderEntity)
{
surface->attachToShader(_renderEntity->getWireShader());
}
}

_attachedToShaders = true;
}

#if 0
void MD5ModelNode::render(IRenderableCollector& collector, const VolumeTest& volume,
const Matrix4& localToWorld, const IRenderEntity& entity) const
{
#if 0
// Do some rough culling (per model, not per surface)
if (volume.TestAABB(localAABB(), localToWorld) == VOLUME_OUTSIDE)
{
Expand All @@ -143,11 +202,11 @@ void MD5ModelNode::render(IRenderableCollector& collector, const VolumeTest& vol
// Uncomment to render the skeleton
//collector.SetState(entity.getWireShader(), RenderableCollector::eFullMaterials);
//collector.addRenderable(_model->getRenderableSkeleton(), localToWorld, entity);
#endif
}
#endif

// Returns the name of the currently active skin
std::string MD5ModelNode::getSkin() const {
std::string MD5ModelNode::getSkin() const
{
return _skin;
}

Expand All @@ -162,8 +221,23 @@ void MD5ModelNode::skinChanged(const std::string& newSkinName)

_model->applySkin(skin);

// Detach from existing shaders, re-acquire them in onPreRender
detachFromShaders();

// Refresh the scene
GlobalSceneGraph().sceneChanged();
}

void MD5ModelNode::onVisibilityChanged(bool isVisibleNow)
{
if (isVisibleNow)
{
attachToShaders();
}
else
{
detachFromShaders();
}
}

} // namespace md5
11 changes: 10 additions & 1 deletion radiantcore/model/md5/MD5ModelNode.h
Expand Up @@ -24,9 +24,10 @@ class MD5ModelNode :
// The renderable surfaces attached to the shaders
std::vector<model::RenderableModelSurface::Ptr> _renderableSurfaces;

bool _attachedToShaders;

public:
MD5ModelNode(const MD5ModelPtr& model);
virtual ~MD5ModelNode();

void onInsertIntoScene(scene::IMapRootNode& root) override;
void onRemoveFromScene(scene::IMapRootNode& root) override;
Expand Down Expand Up @@ -54,6 +55,7 @@ class MD5ModelNode :
bool getIntersection(const Ray& ray, Vector3& intersection) override;

// Renderable implementation
void onPreRender(const VolumeTest& volume) override;
void renderSolid(IRenderableCollector& collector, const VolumeTest& volume) const override;
void renderWireframe(IRenderableCollector& collector, const VolumeTest& volume) const override;
void renderHighlights(IRenderableCollector& collector, const VolumeTest& volume) override;
Expand All @@ -68,9 +70,16 @@ class MD5ModelNode :
virtual std::string getSkin() const override;
void skinChanged(const std::string& newSkinName) override;

protected:
void onVisibilityChanged(bool isVisibleNow) override;

private:
void attachToShaders();
void detachFromShaders();
#if 0
void render(IRenderableCollector& collector, const VolumeTest& volume,
const Matrix4& localToWorld, const IRenderEntity& entity) const;
#endif
};
typedef std::shared_ptr<MD5ModelNode> MD5ModelNodePtr;

Expand Down

0 comments on commit 4336484

Please sign in to comment.