Skip to content

Commit

Permalink
#6009: Re-implement NullModelNode on top of ModelNodeBase
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed Oct 29, 2022
1 parent af383b9 commit 3eec85b
Show file tree
Hide file tree
Showing 11 changed files with 183 additions and 203 deletions.
80 changes: 0 additions & 80 deletions libs/render/RenderableBox.h
Expand Up @@ -200,84 +200,4 @@ class RenderableBox :
}
};

class RenderableBoxSurface final :
public RenderableSurface
{
private:
const AABB& _bounds;
const Matrix4& _orientation;

std::vector<MeshVertex> _vertices;
std::vector<unsigned int> _indices;

public:
RenderableBoxSurface(const AABB& bounds, const Matrix4& orientation) :
_bounds(bounds),
_orientation(orientation)
{
static Vector3 Origin(0, 0, 0);

// Calculate the corner vertices of this bounding box
Vector3 max(Origin + _bounds.extents);
Vector3 min(Origin - _bounds.extents);

auto vertices = detail::getFillBoxVertices(min, max, { 1, 1, 1, 1 });

for (const auto& vertex : vertices)
{
_vertices.push_back(MeshVertex(
toVector3(vertex.vertex),
toVector3(vertex.normal),
Vector2(vertex.texcoord.x(), vertex.texcoord.y()),
Vector4(vertex.colour.x(), vertex.colour.y(), vertex.colour.z(), vertex.colour.w()),
toVector3(vertex.tangent),
toVector3(vertex.bitangent)
));
}

_indices = detail::generateTriangleBoxIndices();
}

bool isVisible() override
{
return !_indices.empty();
}

const std::vector<MeshVertex>& getVertices() override
{
return _vertices;
}

const std::vector<unsigned int>& getIndices() override
{
return _indices;
}

bool isOriented() override
{
return true;
}

const Matrix4& getObjectTransform() override
{
return _orientation;
}

const AABB& getObjectBounds() override
{
return _bounds;
}

bool isShadowCasting() override
{
return false;
}

private:
inline Vector3 toVector3(const Vector3f& vector)
{
return { vector.x(), vector.y(), vector.z() };
}
};

}
108 changes: 108 additions & 0 deletions radiantcore/model/IndexedBoxSurface.h
@@ -0,0 +1,108 @@
#pragma once

#include "RenderableModelSurface.h"
#include "render/RenderableBox.h"

namespace model
{

class IndexedBoxSurface final :
public IIndexedModelSurface
{
private:
const AABB& _bounds;
const Matrix4& _orientation;

std::vector<MeshVertex> _vertices;
std::vector<unsigned int> _indices;

public:
IndexedBoxSurface(const AABB& bounds, const Matrix4& orientation) :
_bounds(bounds),
_orientation(orientation)
{
static Vector3 Origin(0, 0, 0);

// Calculate the corner vertices of this bounding box
Vector3 max(Origin + _bounds.extents);
Vector3 min(Origin - _bounds.extents);

auto vertices = render::detail::getFillBoxVertices(min, max, { 1, 1, 1, 1 });

for (const auto& vertex : vertices)
{
_vertices.push_back(MeshVertex(
toVector3(vertex.vertex),
toVector3(vertex.normal),
Vector2(vertex.texcoord.x(), vertex.texcoord.y()),
Vector4(vertex.colour.x(), vertex.colour.y(), vertex.colour.z(), vertex.colour.w()),
toVector3(vertex.tangent),
toVector3(vertex.bitangent)
));
}

_indices = render::detail::generateTriangleBoxIndices();
}

int getNumVertices() const override
{
return static_cast<int>(_vertices.size());
}

int getNumTriangles() const override
{
return static_cast<int>(_indices.size() / 3); // 3 indices per triangle
}

const MeshVertex& getVertex(int vertexNum) const override
{
return _vertices.at(vertexNum);
}

ModelPolygon getPolygon(int polygonIndex) const override
{
assert(polygonIndex >= 0 && polygonIndex * 3 < static_cast<int>(_indices.size()));

ModelPolygon poly;

poly.a = _vertices[_indices[polygonIndex * 3]];
poly.b = _vertices[_indices[polygonIndex * 3 + 1]];
poly.c = _vertices[_indices[polygonIndex * 3 + 2]];

return poly;
}

const std::string& getDefaultMaterial() const override
{
static std::string _defaultMaterial;
return _defaultMaterial;
}

const std::string& getActiveMaterial() const override
{
return getDefaultMaterial();
}

const AABB& getSurfaceBounds() const override
{
return _bounds;
}

const std::vector<MeshVertex>& getVertexArray() const override
{
return _vertices;
}

const std::vector<unsigned int>& getIndexArray() const override
{
return _indices;
}

private:
inline static Vector3 toVector3(const Vector3f& vector)
{
return { vector.x(), vector.y(), vector.z() };
}
};

}
8 changes: 5 additions & 3 deletions radiantcore/model/ModelNodeBase.cpp
Expand Up @@ -85,7 +85,7 @@ void ModelNodeBase::attachToShaders()

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

// Skip filtered materials - the wireframe shader itself is always visible
// so filtered surfaces need to be kept from attaching their geometry
Expand All @@ -94,8 +94,8 @@ void ModelNodeBase::attachToShaders()
// Solid mode
surface->attachToShader(shader);

// For orthoview rendering we need the entity's wireframe shader
surface->attachToShader(_renderEntity->getWireShader());
// For orthoview rendering we need a wireframe shader
surface->attachToShader(surface->captureWireShader(*renderSystem));

// Attach to the render entity for lighting mode rendering
surface->attachToEntity(_renderEntity, shader);
Expand Down Expand Up @@ -124,6 +124,8 @@ void ModelNodeBase::transformChangedLocal()

void ModelNodeBase::onVisibilityChanged(bool isVisibleNow)
{
Node::onVisibilityChanged(isVisibleNow);

if (isVisibleNow)
{
attachToShaders();
Expand Down
28 changes: 28 additions & 0 deletions radiantcore/model/NullModelBoxSurface.h
@@ -0,0 +1,28 @@
#pragma once

#include "irender.h"
#include "RenderableModelSurface.h"

namespace model
{

class NullModelBoxSurface :
public RenderableModelSurface
{
public:
NullModelBoxSurface(const IIndexedModelSurface& surface, const IRenderEntity* entity, const Matrix4& localToWorld) :
RenderableModelSurface(surface, entity, localToWorld)
{}

ShaderPtr captureWireShader(RenderSystem& renderSystem) override
{
return renderSystem.capture(ColourShaderType::OrthoviewSolid, { 1.0f, 0, 0, 1 });
}

ShaderPtr captureFillShader(RenderSystem& renderSystem) override
{
return renderSystem.capture(BuiltInShaderType::MissingModel);
}
};

}
3 changes: 1 addition & 2 deletions radiantcore/model/NullModelLoader.h
Expand Up @@ -2,7 +2,6 @@

#include "imodel.h"
#include "ifilesystem.h"
#include "itextstream.h"
#include "os/path.h"

#include "NullModelNode.h"
Expand Down Expand Up @@ -48,7 +47,7 @@ class NullModelLoader :
model->setFilename(name);

// Construct a NullModelNode using this resource
return NullModelNodePtr(new NullModelNode(model));
return std::make_shared<NullModelNode>(model);
}

// Required function, not implemented.
Expand Down

0 comments on commit 3eec85b

Please sign in to comment.