[Gtkradiant] r4797 - in GtkRadiant/trunk: docs/developer libs
plugins/entity radiant
svn-noreply at zerowing.idsoftware.com
svn-noreply at zerowing.idsoftware.com
Sat Sep 25 13:01:48 CDT 2004
Author: spog
Date: 2004-09-25 13:01:24 -0500 (Sat, 25 Sep 2004)
New Revision: 4797
Modified:
GtkRadiant/trunk/docs/developer/CHANGES
GtkRadiant/trunk/docs/developer/TODO
GtkRadiant/trunk/libs/allocator.h
GtkRadiant/trunk/libs/auto_array.h
GtkRadiant/trunk/libs/entitylib.h
GtkRadiant/trunk/plugins/entity/entity.cpp
GtkRadiant/trunk/plugins/entity/static.cpp
GtkRadiant/trunk/plugins/entity/static.h
GtkRadiant/trunk/radiant/brush.h
GtkRadiant/trunk/radiant/brush_primit.cpp
GtkRadiant/trunk/radiant/brush_primit.h
GtkRadiant/trunk/radiant/patch.h
Log:
curve control-point editing; BP texture-lock fixes
Modified: GtkRadiant/trunk/docs/developer/CHANGES
===================================================================
--- GtkRadiant/trunk/docs/developer/CHANGES 2004-09-23 19:36:54 UTC (rev 4796)
+++ GtkRadiant/trunk/docs/developer/CHANGES 2004-09-25 18:01:24 UTC (rev 4797)
@@ -1,7 +1,13 @@
This is the changelog for developers, != changelog for the end user
that we distribute with the binaries. (see changelog)
-20/09/2004
+25/09/2004
+SPoG
+- Added component-editing for curves on doom3 entities.
+- Added normalisation of translation for texture-lock on doom3 brushes.
+- Added update of surface inspector for texdef changes caused by texture-lock.
+
+21/09/2004
Michael Schlueter
- Changed file-chooser dialogs to use GtkFileChooser.
Modified: GtkRadiant/trunk/docs/developer/TODO
===================================================================
--- GtkRadiant/trunk/docs/developer/TODO 2004-09-23 19:36:54 UTC (rev 4796)
+++ GtkRadiant/trunk/docs/developer/TODO 2004-09-25 18:01:24 UTC (rev 4797)
@@ -13,10 +13,12 @@
Texture Browser: selecting a texture doesn't properly scroll the textures window to focus on that texture
Shaders: pcx.m8 texture loading broken for heretic2
UI: radiant fails to handle handle the key-up/key-down events when another combination is performed at about the same time (eg CTRL+D).
+texture-lock: faces end up with huge shift values somehow.
HIGH priority features
+Brush: enable per-face filtering
Brush: make edge/vertex/face dragging with QE tool select equal points
Model: add support for doom3 md5anim format
Model: support doom3 .skin files
Modified: GtkRadiant/trunk/libs/allocator.h
===================================================================
--- GtkRadiant/trunk/libs/allocator.h 2004-09-23 19:36:54 UTC (rev 4796)
+++ GtkRadiant/trunk/libs/allocator.h 2004-09-25 18:01:24 UTC (rev 4797)
@@ -169,6 +169,30 @@
#include <algorithm>
+template<typename Type, typename T1>
+class Construct
+{
+ const T1& t;
+public:
+ Construct(const T1& t_) : t(t_)
+ {
+ }
+ void operator()(Type& p)
+ {
+ new(&p) Type(t);
+ }
+};
+
+template<typename Type>
+class Destroy
+{
+public:
+ void operator()(Type& t)
+ {
+ t.~Type();
+ }
+};
+
template<typename Type, typename Allocator = DefaultAllocator<Type> >
class New : public Allocator
{
@@ -208,22 +232,18 @@
{
return new(Allocator::allocate(size)) Type[size];
}
+ template<typename T1>
+ Type* vector(std::size_t size, const T1& t1)
+ {
+ Type* p = reinterpret_cast<Type*>(Allocator::allocate(size));
+ std::for_each(p, p + size, Construct<Type, T1>(t1));
+ return p;
+ }
};
template<typename Type, typename Allocator = DefaultAllocator<Type> >
class Delete : public Allocator
{
- class Destroy : public Allocator
- {
- public:
- Destroy(const Allocator& allocator) : Allocator(allocator)
- {
- }
- void operator()(Type& self)
- {
- self.~Type();
- }
- };
public:
Delete()
{
@@ -244,7 +264,7 @@
{
if(p != 0)
{
- std::for_each(p, p + size, Destroy(*this));
+ std::for_each(p, p + size, Destroy<Type>());
Allocator::deallocate(p, size);
}
}
Modified: GtkRadiant/trunk/libs/auto_array.h
===================================================================
--- GtkRadiant/trunk/libs/auto_array.h 2004-09-23 19:36:54 UTC (rev 4796)
+++ GtkRadiant/trunk/libs/auto_array.h 2004-09-25 18:01:24 UTC (rev 4797)
@@ -22,6 +22,11 @@
return new Element[size];
#endif
}
+ template<typename T1>
+ Element* construct(std::size_t size, const T1& value)
+ {
+ return New<Element, Allocator>(*this).vector(size, value);
+ }
void destroy(Element* data, std::size_t size)
{
#if 1
@@ -44,6 +49,11 @@
: m_size(size), m_data(construct(size))
{
}
+ template<typename T1>
+ auto_array(std::size_t size, const T1& value)
+ : m_size(size), m_data(construct(size, value))
+ {
+ }
auto_array(const auto_array& other)
: m_size(other.size()), m_data(construct(m_size))
{
@@ -129,6 +139,14 @@
temp.swap(*this);
}
}
+ void allocate(std::size_t count, const value_type& value)
+ {
+ if(count != size())
+ {
+ auto_array temp(count, value);
+ temp.swap(*this);
+ }
+ }
};
#endif
Modified: GtkRadiant/trunk/libs/entitylib.h
===================================================================
--- GtkRadiant/trunk/libs/entitylib.h 2004-09-23 19:36:54 UTC (rev 4796)
+++ GtkRadiant/trunk/libs/entitylib.h 2004-09-25 18:01:24 UTC (rev 4797)
@@ -81,7 +81,7 @@
Vector3 points[8];
aabb_corners(aabb, points);
- test.TestQuads(VertexPointer((VertexPointer::pointer)points, sizeof(Vector3)), IndexPointer(indices, 24), best);
+ test.TestQuads(VertexPointer(reinterpret_cast<VertexPointer::pointer>(points), sizeof(Vector3)), IndexPointer(indices, 24), best);
}
inline void aabb_draw_wire(const AABB& aabb)
Modified: GtkRadiant/trunk/plugins/entity/entity.cpp
===================================================================
--- GtkRadiant/trunk/plugins/entity/entity.cpp 2004-09-23 19:36:54 UTC (rev 4796)
+++ GtkRadiant/trunk/plugins/entity/entity.cpp 2004-09-25 18:01:24 UTC (rev 4797)
@@ -366,11 +366,13 @@
Entity_InitFilters(filterTable);
Light_Construct(g_gameType == eGameTypeRTCW);
+ FuncStatic_construct();
//RenderableTargetingEntity::m_state = GlobalShaderCache().Capture("$POINT");
}
void Entity_Destroy()
{
+ FuncStatic_destroy();
Light_Destroy();
//GlobalShaderCache().Release("$POINT");
}
Modified: GtkRadiant/trunk/plugins/entity/static.cpp
===================================================================
--- GtkRadiant/trunk/plugins/entity/static.cpp 2004-09-23 19:36:54 UTC (rev 4796)
+++ GtkRadiant/trunk/plugins/entity/static.cpp 2004-09-25 18:01:24 UTC (rev 4797)
@@ -152,74 +152,322 @@
globalOutputStream() << "t=1 basis=" << BSpline_basis(knots, point, degree, 1.0) << "\n";
}
-class NURBSCurve
+bool ControlPoints_parse(ControlPoints& controlPoints, const char* value)
{
-public:
- ControlPoints m_controlPoints;
- NURBSWeights m_weights;
- Knots m_knots;
- RenderableCurve m_renderCurve;
+ StringTokeniser tokeniser(value, " ");
- bool parseCurve(const char* value)
+ std::size_t size;
+ if(!string_parse_size(tokeniser.getToken(), size))
{
- StringTokeniser tokeniser(value, " ");
+ return false;
+ }
- std::size_t size;
- if(!string_parse_size(tokeniser.getToken(), size))
+ if(size < 3)
+ {
+ return false;
+ }
+ controlPoints.allocate(size);
+
+ if(!string_equal(tokeniser.getToken(), "("))
+ {
+ return false;
+ }
+ for(ControlPoints::iterator i = controlPoints.begin(); i != controlPoints.end(); ++i)
+ {
+ if(!string_parse_float(tokeniser.getToken(), (*i).x())
+ || !string_parse_float(tokeniser.getToken(), (*i).y())
+ || !string_parse_float(tokeniser.getToken(), (*i).z()))
{
return false;
}
+ }
+ if(!string_equal(tokeniser.getToken(), ")"))
+ {
+ return false;
+ }
+ return true;
+}
- if(size < 3)
+void ControlPoints_write(const ControlPoints& controlPoints, StringOutputStream& value)
+{
+ value << static_cast<unsigned int>(controlPoints.size()) << " (";
+ for(ControlPoints::const_iterator i = controlPoints.begin(); i != controlPoints.end(); ++i)
+ {
+ value << " " << (*i).x() << " " << (*i).y() << " " << (*i).z() << " ";
+ }
+ value << ")";
+}
+
+void ControlPoint_testSelect(const Vector3& point, ObservedSelectableInstance& selectable, Selector& selector, SelectionTest& test)
+{
+ select_point_t best;
+ test.TestPoint(point, best);
+ if(best.valid())
+ {
+ selector.pushSelectable(&selectable);
+ selector.addIntersection(best);
+ selector.popSelectable();
+ }
+}
+
+class ControlPointTransform
+{
+ const Matrix4& m_matrix;
+public:
+ ControlPointTransform(const Matrix4& matrix) : m_matrix(matrix)
+ {
+ }
+ void operator()(Vector3& point) const
+ {
+ matrix4_transform_point(m_matrix, point);
+ }
+};
+
+class ControlPointSnap
+{
+ float m_snap;
+public:
+ ControlPointSnap(float snap) : m_snap(snap)
+ {
+ }
+ void operator()(Vector3& point) const
+ {
+ vector3_snap(point, m_snap);
+ }
+};
+
+const colour4b_t colour_vertex(0, 255, 0, 255);
+const colour4b_t colour_selected(0, 0, 255, 255);
+
+class ControlPointAdd
+{
+ RenderablePointVector& m_points;
+public:
+ ControlPointAdd(RenderablePointVector& points) : m_points(points)
+ {
+ }
+ void operator()(const Vector3& point)
+ {
+ m_points.push_back(PointVertex(vertex3f_for_vector3(point), colour_vertex));
+ }
+};
+
+class ControlPointAddSelected
+{
+ RenderablePointVector& m_points;
+public:
+ ControlPointAddSelected(RenderablePointVector& points) : m_points(points)
+ {
+ }
+ void operator()(const Vector3& point)
+ {
+ m_points.push_back(PointVertex(vertex3f_for_vector3(point), colour_selected));
+ }
+};
+
+class CurveEdit
+{
+ SelectionChangeClosure m_selectionChanged;
+ ControlPoints& m_controlPoints;
+ typedef auto_array<ObservedSelectableInstance> Selectables;
+ Selectables m_selectables;
+
+ RenderablePointVector m_controlsRender;
+ mutable RenderablePointVector m_selectedRender;
+
+public:
+ static Shader* m_controlsShader;
+ static Shader* m_selectedShader;
+
+ CurveEdit(ControlPoints& controlPoints, const SelectionChangeClosure& selectionChanged) :
+ m_selectionChanged(selectionChanged),
+ m_controlPoints(controlPoints),
+ m_controlsRender(GL_POINTS),
+ m_selectedRender(GL_POINTS)
+ {
+ }
+
+ template<typename Functor>
+ Functor& forEachSelected(Functor& functor)
+ {
+ RADIANT_ASSERT(m_controlPoints.size() == m_selectables.size(), "curve instance mismatch");
+ ControlPoints::iterator p = m_controlPoints.begin();
+ for(Selectables::iterator i = m_selectables.begin(); i != m_selectables.end(); ++i, ++p)
{
- return false;
+ if((*i).selected())
+ {
+ functor(*p);
+ }
}
- const int BSpline_degree = 3;
+ return functor;
+ }
+ template<typename Functor>
+ Functor& forEachSelected(Functor& functor) const
+ {
+ RADIANT_ASSERT(m_controlPoints.size() == m_selectables.size(), "curve instance mismatch");
+ ControlPoints::const_iterator p = m_controlPoints.begin();
+ for(Selectables::const_iterator i = m_selectables.begin(); i != m_selectables.end(); ++i, ++p)
+ {
+ if((*i).selected())
+ {
+ functor(*p);
+ }
+ }
+ return functor;
+ }
+ template<typename Functor>
+ Functor& forEach(Functor& functor) const
+ {
+ for(ControlPoints::const_iterator i = m_controlPoints.begin(); i != m_controlPoints.end(); ++i)
+ {
+ functor(*i);
+ }
+ return functor;
+ }
- m_weights.allocate(size);
- for(NURBSWeights::iterator i = m_weights.begin(); i != m_weights.end(); ++i)
+ void testSelect(Selector& selector, SelectionTest& test)
+ {
+ RADIANT_ASSERT(m_controlPoints.size() == m_selectables.size(), "curve instance mismatch");
+ ControlPoints::const_iterator p = m_controlPoints.begin();
+ for(Selectables::iterator i = m_selectables.begin(); i != m_selectables.end(); ++i, ++p)
{
- (*i) = 1;
+ ControlPoint_testSelect(*p, *i, selector, test);
}
+ }
- m_controlPoints.allocate(size);
-
- if(!string_equal(tokeniser.getToken(), "("))
+ void select(bool selected)
+ {
+ for(Selectables::iterator i = m_selectables.begin(); i != m_selectables.end(); ++i)
{
- return false;
+ (*i).select(selected);
}
- for(ControlPoints::iterator i = m_controlPoints.begin(); i != m_controlPoints.end(); ++i)
+ }
+
+ void write(const char* key, Entity& entity)
+ {
+ StringOutputStream value(256);
+ if(!m_controlPoints.empty())
{
- if(!string_parse_float(tokeniser.getToken(), (*i).x())
- || !string_parse_float(tokeniser.getToken(), (*i).y())
- || !string_parse_float(tokeniser.getToken(), (*i).z()))
- {
- return false;
- }
+ ControlPoints_write(m_controlPoints, value);
}
- if(!string_equal(tokeniser.getToken(), ")"))
+ entity.setkeyvalue(key, value.c_str());
+ }
+
+ void transform(const Matrix4& matrix)
+ {
+ forEachSelected(ControlPointTransform(matrix));
+ }
+ void snapto(float snap)
+ {
+ forEachSelected(ControlPointSnap(snap));
+ }
+
+ void updateSelected() const
+ {
+ m_selectedRender.clear();
+ forEachSelected(ControlPointAddSelected(m_selectedRender));
+ }
+
+ void renderComponents(IRenderer* renderer, const VolumeTest& volume, const Matrix4& local2world) const
+ {
+ renderer->SetState(m_controlsShader, IRenderer::eWireframeOnly);
+ renderer->SetState(m_controlsShader, IRenderer::eFullMaterials);
+ renderer->Add(&m_controlsRender, local2world);
+
+ updateSelected();
+ if(!m_selectedRender.empty())
{
- return false;
+ renderer->SetState(m_selectedShader, IRenderer::eWireframeOnly);
+ renderer->SetState(m_selectedShader, IRenderer::eFullMaterials);
+ renderer->Add(&m_selectedRender, local2world);
}
+ }
- KnotVector_openUniform(m_knots, m_controlPoints.size(), BSpline_degree);
+ void curveChanged()
+ {
+ m_selectables.allocate(m_controlPoints.size(), m_selectionChanged);
- const std::size_t numSegments = 64;
+ m_controlsRender.clear();
+ m_controlsRender.reserve(m_controlPoints.size());
+ forEach(ControlPointAdd(m_controlsRender));
+
+ m_selectedRender.reserve(m_controlPoints.size());
+ }
+ typedef MemberCaller<CurveEdit>::Caller<&CurveEdit::curveChanged> CurveChangedCaller;
+};
+
+Shader* CurveEdit::m_controlsShader;
+Shader* CurveEdit::m_selectedShader;
+
+
+
+const int NURBS_degree = 3;
+
+class NURBSCurve
+{
+ typedef std::set<Closure> Closures;
+ Closures m_curveChanged;
+ Closure m_boundsChanged;
+public:
+ ControlPoints m_controlPoints;
+ NURBSWeights m_weights;
+ Knots m_knots;
+ RenderableCurve m_renderCurve;
+ AABB m_bounds;
+
+ NURBSCurve(const Closure& boundsChanged) : m_boundsChanged(boundsChanged)
+ {
+ }
+
+ void attach(const Closure& curveChanged)
+ {
+ m_curveChanged.insert(curveChanged);
+ curveChanged();
+ }
+ void detach(const Closure& curveChanged)
+ {
+ m_curveChanged.erase(curveChanged);
+ }
+ void notify()
+ {
+ std::for_each(m_curveChanged.begin(), m_curveChanged.end(), ClosureInvoke());
+ }
+
+ void tesselate()
+ {
+ const std::size_t numSegments = m_controlPoints.size() * 16;
m_renderCurve.m_vertices.resize(numSegments + 1);
m_renderCurve.m_vertices[0].vertex = vertex3f_for_vector3(m_controlPoints[0]);
for(std::size_t i = 1; i < numSegments; ++i)
{
- m_renderCurve.m_vertices[i].vertex = vertex3f_for_vector3(NURBS_evaluate(m_controlPoints, m_weights, m_knots, BSpline_degree, (1.0 / double(numSegments)) * double(i)));
+ m_renderCurve.m_vertices[i].vertex = vertex3f_for_vector3(NURBS_evaluate(m_controlPoints, m_weights, m_knots, NURBS_degree, (1.0 / double(numSegments)) * double(i)));
}
m_renderCurve.m_vertices[numSegments].vertex = vertex3f_for_vector3(m_controlPoints[m_controlPoints.size() - 1]);
+ }
- //plotBasisFunction(8, 0, BSpline_degree);
+ bool parseCurve(const char* value)
+ {
+ if(!ControlPoints_parse(m_controlPoints, value))
+ {
+ return false;
+ }
+ m_weights.allocate(m_controlPoints.size());
+ for(NURBSWeights::iterator i = m_weights.begin(); i != m_weights.end(); ++i)
+ {
+ (*i) = 1;
+ }
+
+ KnotVector_openUniform(m_knots, m_controlPoints.size(), NURBS_degree);
+
+ //plotBasisFunction(8, 0, NURBS_degree);
+
return true;
}
void curveChanged(const char* value)
{
+ m_bounds = AABB();
if(string_empty(value) || !parseCurve(value))
{
m_controlPoints.allocate(0);
@@ -227,53 +475,52 @@
m_weights.allocate(0);
m_renderCurve.m_vertices.clear();
}
+ else
+ {
+ tesselate();
+
+ for(ControlPoints::iterator i = m_controlPoints.begin(); i != m_controlPoints.end(); ++i)
+ {
+ aabb_extend_by_point_safe(m_bounds, (*i));
+ }
+ m_boundsChanged();
+ }
+ notify();
}
typedef MemberCaller1<NURBSCurve, const char*>::Caller<&NURBSCurve::curveChanged> CurveChangedCaller;
};
class CatmullRomSpline
{
+ typedef std::set<Closure> Closures;
+ Closures m_curveChanged;
+ Closure m_boundsChanged;
public:
ControlPoints m_controlPoints;
RenderableCurve m_renderCurve;
+ AABB m_bounds;
- bool parseCurve(const char* value)
+ CatmullRomSpline(const Closure& boundsChanged) : m_boundsChanged(boundsChanged)
{
- StringTokeniser tokeniser(value, " ");
+ }
- std::size_t size;
- if(!string_parse_size(tokeniser.getToken(), size))
- {
- return false;
- }
+ void attach(const Closure& curveChanged)
+ {
+ m_curveChanged.insert(curveChanged);
+ curveChanged();
+ }
+ void detach(const Closure& curveChanged)
+ {
+ m_curveChanged.erase(curveChanged);
+ }
+ void notify()
+ {
+ std::for_each(m_curveChanged.begin(), m_curveChanged.end(), ClosureInvoke());
+ }
- if(size < 3)
- {
- return false;
- }
- const int spline_degree = 3;
-
- m_controlPoints.allocate(size);
-
- if(!string_equal(tokeniser.getToken(), "("))
- {
- return false;
- }
- for(ControlPoints::iterator i = m_controlPoints.begin(); i != m_controlPoints.end(); ++i)
- {
- if(!string_parse_float(tokeniser.getToken(), (*i).x())
- || !string_parse_float(tokeniser.getToken(), (*i).y())
- || !string_parse_float(tokeniser.getToken(), (*i).z()))
- {
- return false;
- }
- }
- if(!string_equal(tokeniser.getToken(), ")"))
- {
- return false;
- }
-
- const std::size_t numSegments = 64;
+ void tesselate()
+ {
+ const std::size_t numSegments = m_controlPoints.size() * 16;
m_renderCurve.m_vertices.resize(numSegments + 1);
m_renderCurve.m_vertices[0].vertex = vertex3f_for_vector3(m_controlPoints[0]);
for(std::size_t i = 1; i < numSegments; ++i)
@@ -281,22 +528,40 @@
m_renderCurve.m_vertices[i].vertex = vertex3f_for_vector3(CatmullRom_evaluate(m_controlPoints, (1.0 / double(numSegments)) * double(i)));
}
m_renderCurve.m_vertices[numSegments].vertex = vertex3f_for_vector3(m_controlPoints[m_controlPoints.size() - 1]);
+ }
- return true;
+ bool parseCurve(const char* value)
+ {
+ return ControlPoints_parse(m_controlPoints, value);
}
void curveChanged(const char* value)
{
+ m_bounds = AABB();
if(string_empty(value) || !parseCurve(value))
{
m_controlPoints.allocate(0);
m_renderCurve.m_vertices.clear();
}
+ else
+ {
+ tesselate();
+
+ for(ControlPoints::iterator i = m_controlPoints.begin(); i != m_controlPoints.end(); ++i)
+ {
+ aabb_extend_by_point_safe(m_bounds, (*i));
+ }
+ m_boundsChanged();
+ }
+ notify();
}
typedef MemberCaller1<CatmullRomSpline, const char*>::Caller<&CatmullRomSpline::curveChanged> CurveChangedCaller;
};
-class FuncStatic : public Editable
+const char* const curve_Nurbs = "curve_Nurbs";
+const char* const curve_CatmullRomSpline = "curve_CatmullRomSpline";
+
+class FuncStatic : public Editable, public Bounded
{
EntityKeyValues m_entity;
KeyObserverMap m_keyObservers;
@@ -313,8 +578,11 @@
NamedEntity m_named;
NameKeys m_nameKeys;
+public:
NURBSCurve m_curveNURBS;
CatmullRomSpline m_curveCatmullRom;
+private:
+ mutable AABB m_curveBounds;
Closure m_transformChanged;
@@ -329,6 +597,7 @@
m_node = node;
node->m_edit = this;
+ node->m_cache = this;
node->m_transform = &m_transform;
node->m_traverse = &m_traverse;
node->m_entity = &m_entity;
@@ -342,8 +611,8 @@
m_keyObservers.insert("angle", Angle::AngleChangedCaller(m_angle));
m_keyObservers.insert("rotation", Rotation::RotationChangedCaller(m_rotation));
m_keyObservers.insert("name", NameChangedCaller(*this));
- m_keyObservers.insert("curve_Nurbs", NURBSCurve::CurveChangedCaller(m_curveNURBS));
- m_keyObservers.insert("curve_CatmullRomSpline", CatmullRomSpline::CurveChangedCaller(m_curveCatmullRom));
+ m_keyObservers.insert(curve_Nurbs, NURBSCurve::CurveChangedCaller(m_curveNURBS));
+ m_keyObservers.insert(curve_CatmullRomSpline, CatmullRomSpline::CurveChangedCaller(m_curveCatmullRom));
m_isModel = false;
m_nameKeys.setKeyIsName(keyIsNameDoom3FuncStatic);
@@ -463,7 +732,7 @@
typedef MemberCaller<FuncStatic>::Caller<&FuncStatic::originChanged> OriginChangedCaller;
public:
- FuncStatic(EntityClass* eclass, scene::Node* node, const Closure& transformChanged) :
+ FuncStatic(EntityClass* eclass, scene::Node* node, const Closure& transformChanged, const Closure& boundsChanged) :
m_entity(eclass),
m_origin(OriginChangedCaller(*this)),
m_angle(UpdateTransformCaller(*this)),
@@ -471,12 +740,14 @@
m_filter(m_entity, node),
m_named(m_entity),
m_transformChanged(transformChanged),
+ m_curveNURBS(boundsChanged),
+ m_curveCatmullRom(boundsChanged),
m_funcStaticOrigin(m_traverse, m_origin),
m_nameKeys(m_entity)
{
construct(node);
}
- FuncStatic(const FuncStatic& other, scene::Node* node, const Closure& transformChanged) :
+ FuncStatic(const FuncStatic& other, scene::Node* node, const Closure& transformChanged, const Closure& boundsChanged) :
m_entity(other.m_entity),
m_origin(OriginChangedCaller(*this)),
m_angle(UpdateTransformCaller(*this)),
@@ -484,6 +755,8 @@
m_filter(m_entity, node),
m_named(m_entity),
m_transformChanged(transformChanged),
+ m_curveNURBS(boundsChanged),
+ m_curveCatmullRom(boundsChanged),
m_funcStaticOrigin(m_traverse, m_origin),
m_nameKeys(m_entity)
{
@@ -536,6 +809,13 @@
m_funcStaticOrigin.detach(observer);
}
+ const AABB& aabb_local() const
+ {
+ m_curveBounds = m_curveNURBS.m_bounds;
+ aabb_extend_by_aabb_safe(m_curveBounds, m_curveCatmullRom.m_bounds);
+ return m_curveBounds;
+ }
+
void render(IRenderer* renderer, const VolumeTest& volume, const Matrix4& local2world) const
{
renderer->SetState(m_entity.eclass().m_state_wire, IRenderer::eWireframeOnly);
@@ -551,6 +831,27 @@
}
}
+ void testSelect(Selector& selector, SelectionTest& test, select_point_t& best)
+ {
+ test.TestLineStrip(
+ VertexPointer(
+ reinterpret_cast<VertexPointer::pointer>(&m_curveNURBS.m_renderCurve.m_vertices[0].vertex),
+ sizeof(PointVertex)
+ ),
+ IndexPointer::index_type(m_curveNURBS.m_renderCurve.m_vertices.size()),
+ best
+ );
+
+ test.TestLineStrip(
+ VertexPointer(
+ reinterpret_cast<VertexPointer::pointer>(&m_curveCatmullRom.m_renderCurve.m_vertices[0].vertex),
+ sizeof(PointVertex)
+ ),
+ IndexPointer::index_type(m_curveCatmullRom.m_renderCurve.m_vertices.size()),
+ best
+ );
+ }
+
// edit
void translate(const Vector3& translation)
{
@@ -575,17 +876,49 @@
}
};
-class FuncStaticInstance : public TargetableInstance, public Renderable
+class ControlPointAddBounds
{
+ AABB& m_bounds;
+public:
+ ControlPointAddBounds(AABB& bounds) : m_bounds(bounds)
+ {
+ }
+ void operator()(const Vector3& point)
+ {
+ aabb_extend_by_point_safe(m_bounds, point);
+ }
+};
+
+class FuncStaticInstance :
+ public TargetableInstance,
+ public Renderable,
+ public Selectable,
+ public ComponentSelectable,
+ public ComponentEditable
+{
FuncStatic& m_group;
+ CurveEdit m_curveNURBS;
+ CurveEdit m_curveCatmullRom;
+ mutable AABB m_aabb_component;
public:
- FuncStaticInstance(const scene::Path& path, scene::Instance* parent, FuncStatic& group) : TargetableInstance(path, parent, group.entity()), m_group(group)
+ FuncStaticInstance(const scene::Path& path, scene::Instance* parent, FuncStatic& group) :
+ TargetableInstance(path, parent, group.entity()),
+ m_group(group),
+ m_curveNURBS(m_group.m_curveNURBS.m_controlPoints, SelectionChangedComponentCaller(*this)),
+ m_curveCatmullRom(m_group.m_curveCatmullRom.m_controlPoints, SelectionChangedComponentCaller(*this))
{
scene::Instance::m_render = this;
+ scene::Instance::m_select = this;
+ scene::Instance::m_component_select = this;
+ scene::Instance::m_component_edit = this;
m_group.instanceAttach(Instance::path());
+ m_group.m_curveNURBS.attach(CurveEdit::CurveChangedCaller(m_curveNURBS));
+ m_group.m_curveCatmullRom.attach(CurveEdit::CurveChangedCaller(m_curveCatmullRom));
}
~FuncStaticInstance()
{
+ m_group.m_curveCatmullRom.detach(CurveEdit::CurveChangedCaller(m_curveCatmullRom));
+ m_group.m_curveNURBS.detach(CurveEdit::CurveChangedCaller(m_curveNURBS));
m_group.instanceDetach(Instance::path());
}
void renderSolid(IRenderer* renderer, const VolumeTest& volume) const
@@ -597,6 +930,101 @@
{
renderSolid(renderer, volume);
}
+ void renderComponents(IRenderer* renderer, const VolumeTest& volume) const
+ {
+ if(GlobalSelectionSystem().ComponentMode() == SelectionSystem::eVertex)
+ {
+ m_curveNURBS.renderComponents(renderer, volume, local2world());
+ m_curveCatmullRom.renderComponents(renderer, volume, local2world());
+ }
+ }
+
+ void testSelect(Selector& selector, SelectionTest& test)
+ {
+ test.BeginMesh(local2world());
+ select_point_t best;
+
+ m_group.testSelect(selector, test, best);
+
+ if(best.valid())
+ {
+ selector.pushSelectable(selectable());
+ selector.addIntersection(best);
+ selector.popSelectable();
+ }
+ }
+
+ void select_component(bool selected, SelectionSystem::EComponentMode mode)
+ {
+ if(mode == SelectionSystem::eVertex)
+ {
+ m_curveNURBS.select(selected);
+ m_curveCatmullRom.select(selected);
+ }
+ }
+ bool selected_component(SelectionSystem::EComponentMode mode) const
+ {
+ return false;
+ }
+ const AABB& aabb_component(SelectionSystem::EComponentMode mode) const
+ {
+ m_aabb_component = AABB();
+ m_curveNURBS.forEachSelected(ControlPointAddBounds(m_aabb_component));
+ m_curveCatmullRom.forEachSelected(ControlPointAddBounds(m_aabb_component));
+ return m_aabb_component;
+ }
+ void testSelect_component(Selector& selector, SelectionTest& test, SelectionSystem::EComponentMode mode)
+ {
+ if(mode == SelectionSystem::eVertex)
+ {
+ test.BeginMesh(local2world());
+ m_curveNURBS.testSelect(selector, test);
+ m_curveCatmullRom.testSelect(selector, test);
+ }
+ }
+
+ void transform_component(const Matrix4& matrix, SelectionSystem::EComponentMode mode)
+ {
+ if(mode == SelectionSystem::eVertex)
+ {
+ m_curveNURBS.transform(matrix);
+ m_curveNURBS.write(curve_Nurbs, m_group.entity());
+
+ m_curveCatmullRom.transform(matrix);
+ m_curveCatmullRom.write(curve_CatmullRomSpline, m_group.entity());
+ }
+ }
+
+ void translate_component(const Vector3& translation, SelectionSystem::EComponentMode mode)
+ {
+ transform_component(matrix4_translation_for_vec3(translation), mode);
+ }
+ void rotate_component(const Quaternion& rotation, SelectionSystem::EComponentMode mode)
+ {
+ transform_component(matrix4_rotation_for_quaternion_quantised(rotation), mode);
+ }
+ void scale_component(const Vector3& scaling, SelectionSystem::EComponentMode mode)
+ {
+ transform_component(matrix4_scale_for_vec3(scaling), mode);
+ }
+ void snapto_component(float snap, SelectionSystem::EComponentMode mode)
+ {
+ if(mode == SelectionSystem::eVertex)
+ {
+ m_curveNURBS.snapto(snap);
+ m_curveNURBS.write(curve_Nurbs, m_group.entity());
+
+ m_curveCatmullRom.snapto(snap);
+ m_curveCatmullRom.write(curve_CatmullRomSpline, m_group.entity());
+ }
+ }
+
+ void selectionChangedComponent(const SelectableInstance& selectable)
+ {
+ GlobalSelectionSystem().getObserver(SelectionSystem::eComponent)(selectable);
+ GlobalSelectionSystem().onComponentSelection(*this, selectable);
+ }
+ typedef MemberCaller1<FuncStaticInstance, const SelectableInstance&>::Caller<&FuncStaticInstance::selectionChangedComponent> SelectionChangedComponentCaller;
};
class FuncStaticNode : public scene::Node::Symbiot, public scene::Instantiable, public scene::Cloneable, public scene::Traversable::Observer
@@ -621,13 +1049,13 @@
public:
FuncStaticNode(EntityClass* eclass) :
m_node(this),
- m_group(eclass, &m_node, Instances::TransformChangedCaller(m_instances))
+ m_group(eclass, &m_node, Instances::TransformChangedCaller(m_instances), Instances::BoundsChangedCaller(m_instances))
{
construct();
}
FuncStaticNode(const FuncStaticNode& other) :
m_node(this),
- m_group(other.m_group, &m_node, Instances::TransformChangedCaller(m_instances))
+ m_group(other.m_group, &m_node, Instances::TransformChangedCaller(m_instances), Instances::BoundsChangedCaller(m_instances))
{
construct();
}
@@ -677,6 +1105,18 @@
}
};
+void FuncStatic_construct()
+{
+ CurveEdit::m_controlsShader = GlobalShaderCache().Capture("$POINT");
+ CurveEdit::m_selectedShader = GlobalShaderCache().Capture("$SELPOINT");
+}
+
+void FuncStatic_destroy()
+{
+ GlobalShaderCache().Release("$SELPOINT");
+ GlobalShaderCache().Release("$POINT");
+}
+
scene::Node* New_FuncStatic(EntityClass* eclass)
{
return (new FuncStaticNode(eclass))->node();
Modified: GtkRadiant/trunk/plugins/entity/static.h
===================================================================
--- GtkRadiant/trunk/plugins/entity/static.h 2004-09-23 19:36:54 UTC (rev 4796)
+++ GtkRadiant/trunk/plugins/entity/static.h 2004-09-25 18:01:24 UTC (rev 4797)
@@ -8,6 +8,8 @@
}
class EntityClass;
+void FuncStatic_construct();
+void FuncStatic_destroy();
scene::Node* New_FuncStatic(EntityClass* eclass);
#endif
Modified: GtkRadiant/trunk/radiant/brush.h
===================================================================
--- GtkRadiant/trunk/radiant/brush.h 2004-09-23 19:36:54 UTC (rev 4796)
+++ GtkRadiant/trunk/radiant/brush.h 2004-09-25 18:01:24 UTC (rev 4797)
@@ -1042,6 +1042,7 @@
if(g_brush_texturelock_enabled)
{
m_texdef.transform(m_plane.plane3(), matrix);
+ g_brush_texture_changed();
}
m_plane.transform(matrix, mirror);
@@ -1103,7 +1104,7 @@
void testSelect(SelectionTest& test, select_point_t& best)
{
- test.TestPolygon(VertexPointer((VertexPointer::pointer)&m_winding.points.data()->vertex, sizeof(WindingVertex)), m_winding.numpoints, best);
+ test.TestPolygon(VertexPointer(reinterpret_cast<VertexPointer::pointer>(&m_winding.points.data()->vertex), sizeof(WindingVertex)), m_winding.numpoints, best);
}
void testSelect_centroid(SelectionTest& test, select_point_t& best)
Modified: GtkRadiant/trunk/radiant/brush_primit.cpp
===================================================================
--- GtkRadiant/trunk/radiant/brush_primit.cpp 2004-09-23 19:36:54 UTC (rev 4796)
+++ GtkRadiant/trunk/radiant/brush_primit.cpp 2004-09-25 18:01:24 UTC (rev 4797)
@@ -191,14 +191,14 @@
}
}
-inline void BPTexdef_fromTransform(brushprimit_texdef_t& bp_texdef, const Matrix4& transform)
+inline void BPTexdef_fromTransform(brushprimit_texdef_t& bp_texdef, float width, float height, const Matrix4& transform)
{
bp_texdef.coords[0][0] = transform.xx();
bp_texdef.coords[0][1] = transform.yx();
- bp_texdef.coords[0][2] = transform.tx();
+ bp_texdef.coords[0][2] = float_mod(transform.tx(), 1.0f);
bp_texdef.coords[1][0] = transform.xy();
bp_texdef.coords[1][1] = transform.yy();
- bp_texdef.coords[1][2] = transform.ty();
+ bp_texdef.coords[1][2] = float_mod(transform.ty(), 1.0f);
}
inline void Texdef_fromTransform(texdef_t& texdef, brushprimit_texdef_t& bp_texdef, float width, float height, const Matrix4& transform)
@@ -208,7 +208,7 @@
if(g_bp_globals.m_bBrushPrimitMode)
{
- BPTexdef_fromTransform(bp_texdef, transform);
+ BPTexdef_fromTransform(bp_texdef, width, height, transform);
}
else
{
Modified: GtkRadiant/trunk/radiant/brush_primit.h
===================================================================
--- GtkRadiant/trunk/radiant/brush_primit.h 2004-09-23 19:36:54 UTC (rev 4796)
+++ GtkRadiant/trunk/radiant/brush_primit.h 2004-09-25 18:01:24 UTC (rev 4797)
@@ -2,6 +2,7 @@
#if !defined(_INCLUDE_BRUSH_PRIMIT_H)
#define _INCLUDE_BRUSH_PRIMIT_H
+#include "math/vector.h"
// Timo
// new brush primitive texdef
struct brushprimit_texdef_t
Modified: GtkRadiant/trunk/radiant/patch.h
===================================================================
--- GtkRadiant/trunk/radiant/patch.h 2004-09-23 19:36:54 UTC (rev 4796)
+++ GtkRadiant/trunk/radiant/patch.h 2004-09-25 18:01:24 UTC (rev 4797)
@@ -1389,8 +1389,12 @@
{
m_render_selected.clear();
for(ctrl_instances_t::const_iterator i = m_ctrl_instances.begin(); i != m_ctrl_instances.end(); ++i)
+ {
if((*i).m_selectable.selected())
+ {
m_render_selected.push_back(PointVertex(reinterpret_cast<vertex3f_t&>((*i).m_ctrl->m_vertex), colour_selected));
+ }
+ }
}
#if 0
@@ -1479,8 +1483,12 @@
m_aabb_component = AABB();
for(ctrl_instances_t::const_iterator i = m_ctrl_instances.begin(); i != m_ctrl_instances.end(); ++i)
+ {
if((*i).m_selectable.selected())
+ {
aabb_extend_by_point_safe(m_aabb_component, (*i).m_ctrl->m_vertex);
+ }
+ }
return m_aabb_component;
}
More information about the Gtkradiant
mailing list