Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Experimental branch to support drag-resizable static meshes
  • Loading branch information
codereader committed Jan 8, 2017
1 parent 63cfe87 commit d27a162
Show file tree
Hide file tree
Showing 19 changed files with 388 additions and 9 deletions.
5 changes: 5 additions & 0 deletions include/iselection.h
Expand Up @@ -57,6 +57,7 @@ class Manipulator
Rotate,
Scale,
Clip,
ModelScale,
Custom
};

Expand All @@ -83,6 +84,10 @@ class Manipulator

virtual ~Manipulator() {}

// ID and Type management
virtual std::size_t getId() const = 0;
virtual void setId(std::size_t id) = 0;

virtual Type getType() const = 0;

/**
Expand Down
1 change: 1 addition & 0 deletions install/user.xml
Expand Up @@ -247,6 +247,7 @@
<toggletoolbutton name="rotate" action="MouseRotate" tooltip="Rotate" icon="select_mouserotate.png"/>
<toggletoolbutton name="resize" action="MouseDrag" tooltip="Resize" icon="select_mouseresize.png"/>
<toggletoolbutton name="clipper" action="ToggleClipper" tooltip="Clipper" icon="view_clipper.png"/>
<toggletoolbutton name="modelscaler" action="ToggleModelScaleManipulator" tooltip="Model Scaler" icon="dragresize_symm.png"/>
<separator/>
<toolbutton name="csgsubstract" action="CSGSubtract" tooltip="CSG Subtract" icon="selection_csgsubtract.png"/>
<toolbutton name="csgmerge" action="CSGMerge" tooltip="CSG Merge" icon="selection_csgmerge.png"/>
Expand Down
3 changes: 3 additions & 0 deletions plugins/entity/EntityNode.cpp
Expand Up @@ -65,6 +65,9 @@ void EntityNode::construct()
_skinKeyObserver.setCallback(std::bind(&ModelKey::skinChanged, &_modelKey, std::placeholders::_1));
addKeyObserver("skin", _skinKeyObserver);

_modelScaleKeyObserver.setCallback(std::bind(&ModelKey::modelScaleChanged, &_modelKey, std::placeholders::_1));
addKeyObserver("dr_model_scale", _modelScaleKeyObserver);

_shaderParms.addKeyObservers();
}

Expand Down
1 change: 1 addition & 0 deletions plugins/entity/EntityNode.h
Expand Up @@ -60,6 +60,7 @@ class EntityNode :
ModelKey _modelKey;
KeyObserverDelegate _modelKeyObserver;
KeyObserverDelegate _skinKeyObserver;
KeyObserverDelegate _modelScaleKeyObserver;

// A helper class managing the collection of KeyObservers attached to the Doom3Entity
KeyObserverMap _keyObservers;
Expand Down
16 changes: 16 additions & 0 deletions plugins/entity/ModelKey.cpp
Expand Up @@ -5,6 +5,7 @@
#include "scene/Node.h"
#include "ifilter.h"
#include "modelskin.h"
#include "itransformable.h"
#include <boost/algorithm/string/replace.hpp>

ModelKey::ModelKey(scene::INode& parentNode) :
Expand Down Expand Up @@ -134,3 +135,18 @@ void ModelKey::skinChanged(const std::string& value)
skinned->skinChanged(value);
}
}

void ModelKey::modelScaleChanged(const std::string& value)
{
if (_modelNode)
{
ITransformablePtr transformable = Node_getTransformable(_modelNode);

if (transformable)
{
transformable->setType(TransformModifierType::TRANSFORM_PRIMITIVE);
transformable->setScale(string::convert<Vector3>(value));
}
}
}

3 changes: 3 additions & 0 deletions plugins/entity/ModelKey.h
Expand Up @@ -36,6 +36,9 @@ class ModelKey
// Gets called by the attached Entity when the "skin" spawnarg changes
void skinChanged(const std::string& value);

// Called when "dr_model_scale" changes
void modelScaleChanged(const std::string& value);

// Returns the reference to the "singleton" model node
const scene::INodePtr& getNode() const;

Expand Down
17 changes: 17 additions & 0 deletions plugins/model/PicoModelNode.cpp
Expand Up @@ -155,4 +155,21 @@ std::string PicoModelNode::getSkin() const
return _skin;
}

void PicoModelNode::_onTransformationChanged()
{
if (getTransformationType() & TransformationType::Scale)
{
_picoModel->evaluateScale(getScale());
}
}

void PicoModelNode::_applyTransformation()
{
if (getTransformationType() & TransformationType::Scale)
{
_picoModel->evaluateScale(getScale());
_picoModel->freezeScale();
}
}

} // namespace model
8 changes: 7 additions & 1 deletion plugins/model/PicoModelNode.h
Expand Up @@ -8,6 +8,7 @@
#include "render/VectorLightList.h"
#include "RenderablePicoModel.h"
#include "scene/Node.h"
#include "Transformable.h"

namespace model {

Expand All @@ -17,7 +18,8 @@ class PicoModelNode :
public SelectionTestable,
public LitObject,
public SkinnedModel,
public ITraceable
public ITraceable,
public Transformable
{
private:
// The actual model
Expand Down Expand Up @@ -90,6 +92,10 @@ class PicoModelNode :
// Traceable implementation
bool getIntersection(const Ray& ray, Vector3& intersection);

protected:
virtual void _onTransformationChanged() override;
virtual void _applyTransformation() override;

private:
// Instance render function
void submitRenderables(RenderableCollector& collector,
Expand Down
26 changes: 26 additions & 0 deletions plugins/model/RenderablePicoModel.cpp
Expand Up @@ -53,6 +53,7 @@ RenderablePicoModel::RenderablePicoModel(const RenderablePicoModel& other) :
for (std::size_t i = 0; i < other._surfVec.size(); ++i)
{
_surfVec[i].surface = other._surfVec[i].surface;
_surfVec[i].originalSurface = other._surfVec[i].originalSurface;
_surfVec[i].activeMaterial = _surfVec[i].surface->getDefaultMaterial();
}
}
Expand Down Expand Up @@ -307,4 +308,29 @@ void RenderablePicoModel::setModelPath(const std::string& modelPath)
_modelPath = modelPath;
}

void RenderablePicoModel::evaluateScale(const Vector3& scale)
{
// Apply the scale to each surface
for (Surface& surf : _surfVec)
{
// Are we still using the original surface? If yes,
// it's now time to create a working copy
if (surf.surface == surf.originalSurface)
{
// Copy-construct the surface
surf.surface = std::make_shared<RenderablePicoSurface>(*surf.originalSurface);
}

// Apply the scale, on top of the original surface, this should save us from
// reverting the transformation each time the scale changes
surf.surface->applyScale(scale, *(surf.originalSurface));
}
}

// Freeze transform, move the applied scale to the original model
void RenderablePicoModel::freezeScale()
{
// TODO
}

} // namespace
12 changes: 11 additions & 1 deletion plugins/model/RenderablePicoModel.h
Expand Up @@ -41,6 +41,9 @@ class RenderablePicoModel
// The (shared) surface object
RenderablePicoSurfacePtr surface;

// The (unmodified) surface object
RenderablePicoSurfacePtr originalSurface;

// The name of the material (with skin applied)
// The default material name is stored on the surface
std::string activeMaterial;
Expand All @@ -53,7 +56,8 @@ class RenderablePicoModel

// Constructor
Surface(const RenderablePicoSurfacePtr& surface_) :
surface(surface_)
surface(surface_),
originalSurface(surface)
{}
};

Expand Down Expand Up @@ -200,6 +204,12 @@ class RenderablePicoModel
const SurfaceList& getSurfaces() const {
return _surfVec;
}

// TransformationChanged, apply the given scale to the "working copy"
void evaluateScale(const Vector3& scale);

// Freeze transform, move the applied scale to the original model
void freezeScale();
};
typedef std::shared_ptr<RenderablePicoModel> RenderablePicoModelPtr;

Expand Down
46 changes: 44 additions & 2 deletions plugins/model/RenderablePicoSurface.cpp
@@ -1,5 +1,6 @@
#include "RenderablePicoSurface.h"

#include "itextstream.h"
#include "modelskin.h"
#include "math/Frustum.h"
#include "math/Ray.h"
Expand Down Expand Up @@ -60,18 +61,20 @@ RenderablePicoSurface::RenderablePicoSurface(picoSurface_t* surf,
_vertices.resize(nVerts);
_indices.resize(_nIndices);

// Stream in the vertex data from the raw struct, expanding the local AABB
// Stream in the vertex data from the raw struct, expanding the local AABB
// to include each vertex.
for (int vNum = 0; vNum < nVerts; ++vNum) {

// Get the vertex position and colour
Vertex3f vertex(PicoGetSurfaceXYZ(surf, vNum));

Normal3f normal = PicoGetSurfaceNormal(surf, vNum);

// Expand the AABB to include this new vertex
_localAABB.includePoint(vertex);

_vertices[vNum].vertex = vertex;
_vertices[vNum].normal = Normal3f(PicoGetSurfaceNormal(surf, vNum));
_vertices[vNum].normal = normal;
_vertices[vNum].texcoord = TexCoord2f(PicoGetSurfaceST(surf, 0, vNum));
_vertices[vNum].colour =
getColourVector(PicoGetSurfaceColor(surf, 0, vNum));
Expand All @@ -89,6 +92,19 @@ RenderablePicoSurface::RenderablePicoSurface(picoSurface_t* surf,
createDisplayLists();
}

RenderablePicoSurface::RenderablePicoSurface(const RenderablePicoSurface& other) :
_shaderName(other._shaderName),
_vertices(other._vertices),
_indices(other._indices),
_nIndices(other._nIndices),
_localAABB(other._localAABB),
_dlRegular(0),
_dlProgramVcol(0),
_dlProgramNoVCol(0)
{
createDisplayLists();
}

std::string RenderablePicoSurface::cleanupShaderName(const std::string& inName)
{
const std::string baseFolder = "base"; //FIXME: should be from game.xml
Expand Down Expand Up @@ -383,4 +399,30 @@ bool RenderablePicoSurface::getIntersection(const Ray& ray, Vector3& intersectio
}
}

void RenderablePicoSurface::applyScale(const Vector3& scale, const RenderablePicoSurface& originalSurface)
{
if (scale.x() == 0 || scale.y() == 0 || scale.z() == 0)
{
rMessage() << "RenderablePicoSurface: Cannot apply scale with a zero diagonal element" << std::endl;
return;
}

Matrix4 scaleMatrix = Matrix4::getScale(scale);
Matrix4 invTranspScale = Matrix4::getScale(Vector3(1/scale.x(), 1/scale.y(), 1/scale.z()));

assert(originalSurface.getNumVertices() == getNumVertices());

for (std::size_t i = 0; i < _vertices.size(); ++i)
{
_vertices[i].vertex = scaleMatrix.transformPoint(originalSurface._vertices[i].vertex);
_vertices[i].normal = invTranspScale.transformPoint(originalSurface._vertices[i].normal);
}

glDeleteLists(_dlRegular, 1);
glDeleteLists(_dlProgramNoVCol, 1);
glDeleteLists(_dlProgramVcol, 1);

createDisplayLists();
}

} // namespace model
10 changes: 6 additions & 4 deletions plugins/model/RenderablePicoSurface.h
Expand Up @@ -74,6 +74,11 @@ class RenderablePicoSurface :
*/
RenderablePicoSurface(picoSurface_t* surf, const std::string& fExt);

/**
* Copy-constructor.
*/
RenderablePicoSurface(const RenderablePicoSurface& other);

/**
* Destructor.
*/
Expand All @@ -97,8 +102,6 @@ class RenderablePicoSurface :
void submitRenderables(RenderableCollector& rend, const Matrix4& localToWorld,
const ShaderPtr& shader, const IRenderEntity& entity);

void setRenderSystem(const RenderSystemPtr& renderSystem);

/**
* Render function from OpenGLRenderable
*/
Expand Down Expand Up @@ -131,8 +134,7 @@ class RenderablePicoSurface :
// the exact point in the given Vector3, returns false if no intersection was found.
bool getIntersection(const Ray& ray, Vector3& intersection, const Matrix4& localToWorld);

private:
void captureShader();
void applyScale(const Vector3& scale, const RenderablePicoSurface& originalSurface);
};
typedef std::shared_ptr<RenderablePicoSurface> RenderablePicoSurfacePtr;

Expand Down

0 comments on commit d27a162

Please sign in to comment.