X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fnetradiant.git;a=blobdiff_plain;f=plugins%2Fentity%2Fdoom3group.cpp;h=a891fd6746b699c6d89644385cb39fa3ccfb5b8f;hp=66e2f9249f03acd58fcf605324b9c5cc00fdb1c1;hb=9dfae1c9b270ee369c6362903a9205b30751b95f;hpb=231225d6f97d0b926b2e896e5783cccfbc7c5619 diff --git a/plugins/entity/doom3group.cpp b/plugins/entity/doom3group.cpp index 66e2f924..a891fd67 100644 --- a/plugins/entity/doom3group.cpp +++ b/plugins/entity/doom3group.cpp @@ -1,23 +1,23 @@ /* -Copyright (C) 2001-2006, William Joseph. -All Rights Reserved. + Copyright (C) 2001-2006, William Joseph. + All Rights Reserved. -This file is part of GtkRadiant. + This file is part of GtkRadiant. -GtkRadiant is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + GtkRadiant is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -GtkRadiant is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + GtkRadiant is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with GtkRadiant; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + You should have received a copy of the GNU General Public License + along with GtkRadiant; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ ///\file ///\brief Represents any Doom3 entity which does not have a fixed size specified in its entity-definition (e.g. func_static). @@ -58,775 +58,797 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "entity.h" -inline void PointVertexArray_testSelect(PointVertex* first, std::size_t count, SelectionTest& test, SelectionIntersection& best) +inline void +PointVertexArray_testSelect(PointVertex *first, std::size_t count, SelectionTest &test, SelectionIntersection &best) { - test.TestLineStrip( - VertexPointer( - reinterpret_cast(&first->vertex), - sizeof(PointVertex) - ), - IndexPointer::index_type(count), - best - ); + test.TestLineStrip( + VertexPointer( + reinterpret_cast( &first->vertex ), + sizeof(PointVertex) + ), + IndexPointer::index_type(count), + best + ); } class Doom3Group : - public Bounded, - public Snappable -{ - EntityKeyValues m_entity; - KeyObserverMap m_keyObservers; - TraversableNodeSet m_traverse; - MatrixTransform m_transform; - - SingletonModel m_model; - OriginKey m_originKey; - Vector3 m_origin; - - RotationKey m_rotationKey; - Float9 m_rotation; - - ClassnameFilter m_filter; - NamedEntity m_named; - NameKeys m_nameKeys; - TraversableObserverPairRelay m_traverseObservers; - Doom3GroupOrigin m_funcStaticOrigin; - RenderablePivot m_renderOrigin; - RenderableNamedEntity m_renderName; - mutable Vector3 m_name_origin; - ModelSkinKey m_skin; + public Bounded, + public Snappable { + EntityKeyValues m_entity; + KeyObserverMap m_keyObservers; + TraversableNodeSet m_traverse; + MatrixTransform m_transform; + + SingletonModel m_model; + OriginKey m_originKey; + Vector3 m_origin; + + RotationKey m_rotationKey; + Float9 m_rotation; + + ClassnameFilter m_filter; + NamedEntity m_named; + NameKeys m_nameKeys; + TraversableObserverPairRelay m_traverseObservers; + Doom3GroupOrigin m_funcStaticOrigin; + RenderablePivot m_renderOrigin; + RenderableNamedEntity m_renderName; + mutable Vector3 m_name_origin; + ModelSkinKey m_skin; public: - NURBSCurve m_curveNURBS; - SignalHandlerId m_curveNURBSChanged; - CatmullRomSpline m_curveCatmullRom; - SignalHandlerId m_curveCatmullRomChanged; + NURBSCurve m_curveNURBS; + SignalHandlerId m_curveNURBSChanged; + CatmullRomSpline m_curveCatmullRom; + SignalHandlerId m_curveCatmullRomChanged; private: - mutable AABB m_curveBounds; - - Callback m_transformChanged; - Callback m_evaluateTransform; - - CopiedString m_name; - CopiedString m_modelKey; - bool m_isModel; - - scene::Traversable* m_traversable; - - void construct() - { - default_rotation(m_rotation); - - m_keyObservers.insert("classname", ClassnameFilter::ClassnameChangedCaller(m_filter)); - m_keyObservers.insert(Static::instance().m_nameKey, NamedEntity::IdentifierChangedCaller(m_named)); - m_keyObservers.insert("model", Doom3Group::ModelChangedCaller(*this)); - m_keyObservers.insert("origin", OriginKey::OriginChangedCaller(m_originKey)); - m_keyObservers.insert("angle", RotationKey::AngleChangedCaller(m_rotationKey)); - m_keyObservers.insert("rotation", RotationKey::RotationChangedCaller(m_rotationKey)); - 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("skin", ModelSkinKey::SkinChangedCaller(m_skin)); - - m_traverseObservers.attach(m_funcStaticOrigin); - m_isModel = false; - m_nameKeys.setKeyIsName(keyIsNameDoom3Doom3Group); - attachTraverse(); - - m_entity.attach(m_keyObservers); - } - void destroy() - { - m_entity.detach(m_keyObservers); - - if(isModel()) - { - detachModel(); - } - else - { - detachTraverse(); - } - - m_traverseObservers.detach(m_funcStaticOrigin); - } - - void attachModel() - { - m_traversable = &m_model.getTraversable(); - m_model.attach(&m_traverseObservers); - } - void detachModel() - { - m_traversable = 0; - m_model.detach(&m_traverseObservers); - } - void attachTraverse() - { - m_traversable = &m_traverse; - m_traverse.attach(&m_traverseObservers); - } - void detachTraverse() - { - m_traversable = 0; - m_traverse.detach(&m_traverseObservers); - } - - bool isModel() const - { - return m_isModel; - } - - void setIsModel(bool newValue) - { - if(newValue && !m_isModel) - { - detachTraverse(); - attachModel(); - - m_nameKeys.setKeyIsName(Static::instance().m_keyIsName); - m_model.modelChanged(m_modelKey.c_str()); - } - else if(!newValue && m_isModel) - { - detachModel(); - attachTraverse(); - - m_nameKeys.setKeyIsName(keyIsNameDoom3Doom3Group); - } - m_isModel = newValue; - updateTransform(); - } - - void updateIsModel() - { - setIsModel(!string_equal(m_modelKey.c_str(), m_name.c_str())); - } + mutable AABB m_curveBounds; + + Callback m_transformChanged; + Callback m_evaluateTransform; + + CopiedString m_name; + CopiedString m_modelKey; + bool m_isModel; + + scene::Traversable *m_traversable; + + void construct() + { + default_rotation(m_rotation); + + m_keyObservers.insert("classname", ClassnameFilter::ClassnameChangedCaller(m_filter)); + m_keyObservers.insert(Static::instance().m_nameKey, NamedEntity::IdentifierChangedCaller(m_named)); + m_keyObservers.insert("model", Doom3Group::ModelChangedCaller(*this)); + m_keyObservers.insert("origin", OriginKey::OriginChangedCaller(m_originKey)); + m_keyObservers.insert("angle", RotationKey::AngleChangedCaller(m_rotationKey)); + m_keyObservers.insert("rotation", RotationKey::RotationChangedCaller(m_rotationKey)); + 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("skin", ModelSkinKey::SkinChangedCaller(m_skin)); + + m_traverseObservers.attach(m_funcStaticOrigin); + m_isModel = false; + m_nameKeys.setKeyIsName(keyIsNameDoom3Doom3Group); + attachTraverse(); + + m_entity.attach(m_keyObservers); + } + + void destroy() + { + m_entity.detach(m_keyObservers); + + if (isModel()) { + detachModel(); + } else { + detachTraverse(); + } + + m_traverseObservers.detach(m_funcStaticOrigin); + } + + void attachModel() + { + m_traversable = &m_model.getTraversable(); + m_model.attach(&m_traverseObservers); + } + + void detachModel() + { + m_traversable = 0; + m_model.detach(&m_traverseObservers); + } + + void attachTraverse() + { + m_traversable = &m_traverse; + m_traverse.attach(&m_traverseObservers); + } + + void detachTraverse() + { + m_traversable = 0; + m_traverse.detach(&m_traverseObservers); + } + + bool isModel() const + { + return m_isModel; + } + + void setIsModel(bool newValue) + { + if (newValue && !m_isModel) { + detachTraverse(); + attachModel(); + + m_nameKeys.setKeyIsName(Static::instance().m_keyIsName); + m_model.modelChanged(m_modelKey.c_str()); + } else if (!newValue && m_isModel) { + detachModel(); + attachTraverse(); + + m_nameKeys.setKeyIsName(keyIsNameDoom3Doom3Group); + } + m_isModel = newValue; + updateTransform(); + } + + void updateIsModel() + { + setIsModel(!string_equal(m_modelKey.c_str(), m_name.c_str())); + } // vc 2k5 compiler fix #if _MSC_VER >= 1400 - public: + public: #endif - void nameChanged(const char* value) - { - m_name = value; - updateIsModel(); - } - typedef MemberCaller1 NameChangedCaller; - - void modelChanged(const char* value) - { - m_modelKey = value; - updateIsModel(); - if(isModel()) + void nameChanged(const char *value) { - m_model.modelChanged(value); + m_name = value; + updateIsModel(); } - else + + typedef MemberCaller NameChangedCaller; + + void modelChanged(const char *value) { - m_model.modelChanged(""); + m_modelKey = value; + updateIsModel(); + if (isModel()) { + m_model.modelChanged(value); + } else { + m_model.modelChanged(""); + } } - } - typedef MemberCaller1 ModelChangedCaller; - void updateTransform() - { - m_transform.localToParent() = g_matrix4_identity; - if(isModel()) + typedef MemberCaller ModelChangedCaller; + + void updateTransform() { - matrix4_translate_by_vec3(m_transform.localToParent(), m_origin); - matrix4_multiply_by_matrix4(m_transform.localToParent(), rotation_toMatrix(m_rotation)); + m_transform.localToParent() = g_matrix4_identity; + if (isModel()) { + matrix4_translate_by_vec3(m_transform.localToParent(), m_origin); + matrix4_multiply_by_matrix4(m_transform.localToParent(), rotation_toMatrix(m_rotation)); + } + m_transformChanged(); + if (!isModel()) { + m_funcStaticOrigin.originChanged(); + } } - m_transformChanged(); - if(!isModel()) + + typedef MemberCaller UpdateTransformCaller; + + void originChanged() { - m_funcStaticOrigin.originChanged(); + m_origin = m_originKey.m_origin; + updateTransform(); } - } - typedef MemberCaller UpdateTransformCaller; - void originChanged() - { - m_origin = m_originKey.m_origin; - updateTransform(); - } - typedef MemberCaller OriginChangedCaller; + typedef MemberCaller OriginChangedCaller; - void rotationChanged() - { - rotation_assign(m_rotation, m_rotationKey.m_rotation); - updateTransform(); - } - typedef MemberCaller RotationChangedCaller; + void rotationChanged() + { + rotation_assign(m_rotation, m_rotationKey.m_rotation); + updateTransform(); + } - void skinChanged() - { - if(isModel()) + typedef MemberCaller RotationChangedCaller; + + void skinChanged() { - scene::Node* node = m_model.getNode(); - if(node != 0) - { - Node_modelSkinChanged(*node); - } + if (isModel()) { + scene::Node *node = m_model.getNode(); + if (node != 0) { + Node_modelSkinChanged(*node); + } + } } - } - typedef MemberCaller SkinChangedCaller; -public: - Doom3Group(EntityClass* eclass, scene::Node& node, const Callback& transformChanged, const Callback& boundsChanged, const Callback& evaluateTransform) : - m_entity(eclass), - m_originKey(OriginChangedCaller(*this)), - m_origin(ORIGINKEY_IDENTITY), - m_rotationKey(RotationChangedCaller(*this)), - m_filter(m_entity, node), - m_named(m_entity), - m_nameKeys(m_entity), - m_funcStaticOrigin(m_traverse, m_origin), - m_renderName(m_named, m_name_origin), - m_name_origin(g_vector3_identity), - m_skin(SkinChangedCaller(*this)), - m_curveNURBS(boundsChanged), - m_curveCatmullRom(boundsChanged), - m_transformChanged(transformChanged), - m_evaluateTransform(evaluateTransform), - m_traversable(0) - { - construct(); - } - Doom3Group(const Doom3Group& other, scene::Node& node, const Callback& transformChanged, const Callback& boundsChanged, const Callback& evaluateTransform) : - m_entity(other.m_entity), - m_originKey(OriginChangedCaller(*this)), - m_origin(ORIGINKEY_IDENTITY), - m_rotationKey(RotationChangedCaller(*this)), - m_filter(m_entity, node), - m_named(m_entity), - m_nameKeys(m_entity), - m_funcStaticOrigin(m_traverse, m_origin), - m_renderName(m_named, g_vector3_identity), - m_skin(SkinChangedCaller(*this)), - m_curveNURBS(boundsChanged), - m_curveCatmullRom(boundsChanged), - m_transformChanged(transformChanged), - m_evaluateTransform(evaluateTransform), - m_traversable(0) - { - construct(); - } - ~Doom3Group() - { - destroy(); - } - - InstanceCounter m_instanceCounter; - void instanceAttach(const scene::Path& path) - { - if(++m_instanceCounter.m_count == 1) - { - m_filter.instanceAttach(); - m_entity.instanceAttach(path_find_mapfile(path.begin(), path.end())); - m_traverse.instanceAttach(path_find_mapfile(path.begin(), path.end())); - - m_funcStaticOrigin.enable(); - } - } - void instanceDetach(const scene::Path& path) - { - if(--m_instanceCounter.m_count == 0) - { - m_funcStaticOrigin.disable(); - - m_traverse.instanceDetach(path_find_mapfile(path.begin(), path.end())); - m_entity.instanceDetach(path_find_mapfile(path.begin(), path.end())); - m_filter.instanceDetach(); - } - } - - EntityKeyValues& getEntity() - { - return m_entity; - } - const EntityKeyValues& getEntity() const - { - return m_entity; - } - - scene::Traversable& getTraversable() - { - return *m_traversable; - } - Namespaced& getNamespaced() - { - return m_nameKeys; - } - Nameable& getNameable() - { - return m_named; - } - TransformNode& getTransformNode() - { - return m_transform; - } - ModelSkin& getModelSkin() - { - return m_skin.get(); - } - - void attach(scene::Traversable::Observer* observer) - { - m_traverseObservers.attach(*observer); - } - void detach(scene::Traversable::Observer* observer) - { - m_traverseObservers.detach(*observer); - } - - const AABB& localAABB() const - { - m_curveBounds = m_curveNURBS.m_bounds; - aabb_extend_by_aabb_safe(m_curveBounds, m_curveCatmullRom.m_bounds); - return m_curveBounds; - } - - void renderSolid(Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld, bool selected) const - { - if(isModel() && selected) - { - m_renderOrigin.render(renderer, volume, localToWorld); - } - - renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly); - renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eFullMaterials); - - if(!m_curveNURBS.m_renderCurve.m_vertices.empty()) - { - renderer.addRenderable(m_curveNURBS.m_renderCurve, localToWorld); - } - if(!m_curveCatmullRom.m_renderCurve.m_vertices.empty()) - { - renderer.addRenderable(m_curveCatmullRom.m_renderCurve, localToWorld); - } - } - - void renderWireframe(Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld, bool selected, const AABB& childBounds) const - { - renderSolid(renderer, volume, localToWorld, selected); - - if(g_showNames) - { - // draw models as usual - if(!isModel()) - { - // don't draw the name for worldspawn - if(!strcmp(m_entity.getEntityClass().name(), "worldspawn")) - return; - - // place name in the middle of the "children cloud" - m_name_origin = childBounds.origin; - } - - renderer.addRenderable(m_renderName, localToWorld); - } - } - - void testSelect(Selector& selector, SelectionTest& test, SelectionIntersection& best) - { - PointVertexArray_testSelect(&m_curveNURBS.m_renderCurve.m_vertices[0], m_curveNURBS.m_renderCurve.m_vertices.size(), test, best); - PointVertexArray_testSelect(&m_curveCatmullRom.m_renderCurve.m_vertices[0], m_curveCatmullRom.m_renderCurve.m_vertices.size(), test, best); - } - - void translate(const Vector3& translation) - { - m_origin = origin_translated(m_origin, translation); - } - void rotate(const Quaternion& rotation) - { - rotation_rotate(m_rotation, rotation); - } - void snapto(float snap) - { - m_originKey.m_origin = origin_snapped(m_originKey.m_origin, snap); - m_originKey.write(&m_entity); - } - void revertTransform() - { - m_origin = m_originKey.m_origin; - rotation_assign(m_rotation, m_rotationKey.m_rotation); - m_curveNURBS.m_controlPointsTransformed = m_curveNURBS.m_controlPoints; - m_curveCatmullRom.m_controlPointsTransformed = m_curveCatmullRom.m_controlPoints; - } - void freezeTransform() - { - m_originKey.m_origin = m_origin; - m_originKey.write(&m_entity); - rotation_assign(m_rotationKey.m_rotation, m_rotation); - m_rotationKey.write(&m_entity); - m_curveNURBS.m_controlPoints = m_curveNURBS.m_controlPointsTransformed; - ControlPoints_write(m_curveNURBS.m_controlPoints, curve_Nurbs, m_entity); - m_curveCatmullRom.m_controlPoints = m_curveCatmullRom.m_controlPointsTransformed; - ControlPoints_write(m_curveCatmullRom.m_controlPoints, curve_CatmullRomSpline, m_entity); - } - void transformChanged() - { - revertTransform(); - m_evaluateTransform(); - updateTransform(); - m_curveNURBS.curveChanged(); - m_curveCatmullRom.curveChanged(); - } - typedef MemberCaller TransformChangedCaller; -}; + typedef MemberCaller SkinChangedCaller; -class ControlPointAddBounds -{ - AABB& m_bounds; public: - ControlPointAddBounds(AABB& bounds) : m_bounds(bounds) - { - } - void operator()(const Vector3& point) const - { - aabb_extend_by_point_safe(m_bounds, point); - } + Doom3Group(EntityClass *eclass, scene::Node &node, const Callback &transformChanged, + const Callback &boundsChanged, const Callback &evaluateTransform) : + m_entity(eclass), + m_originKey(OriginChangedCaller(*this)), + m_origin(ORIGINKEY_IDENTITY), + m_rotationKey(RotationChangedCaller(*this)), + m_filter(m_entity, node), + m_named(m_entity), + m_nameKeys(m_entity), + m_funcStaticOrigin(m_traverse, m_origin), + m_renderName(m_named, m_name_origin), + m_name_origin(g_vector3_identity), + m_skin(SkinChangedCaller(*this)), + m_curveNURBS(boundsChanged), + m_curveCatmullRom(boundsChanged), + m_transformChanged(transformChanged), + m_evaluateTransform(evaluateTransform), + m_traversable(0) + { + construct(); + } + + Doom3Group(const Doom3Group &other, scene::Node &node, const Callback &transformChanged, + const Callback &boundsChanged, const Callback &evaluateTransform) : + m_entity(other.m_entity), + m_originKey(OriginChangedCaller(*this)), + m_origin(ORIGINKEY_IDENTITY), + m_rotationKey(RotationChangedCaller(*this)), + m_filter(m_entity, node), + m_named(m_entity), + m_nameKeys(m_entity), + m_funcStaticOrigin(m_traverse, m_origin), + m_renderName(m_named, g_vector3_identity), + m_skin(SkinChangedCaller(*this)), + m_curveNURBS(boundsChanged), + m_curveCatmullRom(boundsChanged), + m_transformChanged(transformChanged), + m_evaluateTransform(evaluateTransform), + m_traversable(0) + { + construct(); + } + + ~Doom3Group() + { + destroy(); + } + + InstanceCounter m_instanceCounter; + + void instanceAttach(const scene::Path &path) + { + if (++m_instanceCounter.m_count == 1) { + m_filter.instanceAttach(); + m_entity.instanceAttach(path_find_mapfile(path.begin(), path.end())); + m_traverse.instanceAttach(path_find_mapfile(path.begin(), path.end())); + + m_funcStaticOrigin.enable(); + } + } + + void instanceDetach(const scene::Path &path) + { + if (--m_instanceCounter.m_count == 0) { + m_funcStaticOrigin.disable(); + + m_traverse.instanceDetach(path_find_mapfile(path.begin(), path.end())); + m_entity.instanceDetach(path_find_mapfile(path.begin(), path.end())); + m_filter.instanceDetach(); + } + } + + EntityKeyValues &getEntity() + { + return m_entity; + } + + const EntityKeyValues &getEntity() const + { + return m_entity; + } + + scene::Traversable &getTraversable() + { + return *m_traversable; + } + + Namespaced &getNamespaced() + { + return m_nameKeys; + } + + Nameable &getNameable() + { + return m_named; + } + + TransformNode &getTransformNode() + { + return m_transform; + } + + ModelSkin &getModelSkin() + { + return m_skin.get(); + } + + void attach(scene::Traversable::Observer *observer) + { + m_traverseObservers.attach(*observer); + } + + void detach(scene::Traversable::Observer *observer) + { + m_traverseObservers.detach(*observer); + } + + const AABB &localAABB() const + { + m_curveBounds = m_curveNURBS.m_bounds; + aabb_extend_by_aabb_safe(m_curveBounds, m_curveCatmullRom.m_bounds); + return m_curveBounds; + } + + void renderSolid(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld, bool selected) const + { + if (isModel() && selected) { + m_renderOrigin.render(renderer, volume, localToWorld); + } + + renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly); + renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eFullMaterials); + + if (!m_curveNURBS.m_renderCurve.m_vertices.empty()) { + renderer.addRenderable(m_curveNURBS.m_renderCurve, localToWorld); + } + if (!m_curveCatmullRom.m_renderCurve.m_vertices.empty()) { + renderer.addRenderable(m_curveCatmullRom.m_renderCurve, localToWorld); + } + } + + void renderWireframe(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld, bool selected, + const AABB &childBounds) const + { + renderSolid(renderer, volume, localToWorld, selected); + + if (g_showNames) { + // draw models as usual + if (!isModel()) { + // don't draw the name for worldspawn + if (!strcmp(m_entity.getEntityClass().name(), "worldspawn")) { + return; + } + + // place name in the middle of the "children cloud" + m_name_origin = childBounds.origin; + } + + renderer.addRenderable(m_renderName, localToWorld); + } + } + + void testSelect(Selector &selector, SelectionTest &test, SelectionIntersection &best) + { + PointVertexArray_testSelect(&m_curveNURBS.m_renderCurve.m_vertices[0], + m_curveNURBS.m_renderCurve.m_vertices.size(), test, best); + PointVertexArray_testSelect(&m_curveCatmullRom.m_renderCurve.m_vertices[0], + m_curveCatmullRom.m_renderCurve.m_vertices.size(), test, best); + } + + void translate(const Vector3 &translation) + { + m_origin = origin_translated(m_origin, translation); + } + + void rotate(const Quaternion &rotation) + { + rotation_rotate(m_rotation, rotation); + } + + void snapto(float snap) + { + m_originKey.m_origin = origin_snapped(m_originKey.m_origin, snap); + m_originKey.write(&m_entity); + } + + void revertTransform() + { + m_origin = m_originKey.m_origin; + rotation_assign(m_rotation, m_rotationKey.m_rotation); + m_curveNURBS.m_controlPointsTransformed = m_curveNURBS.m_controlPoints; + m_curveCatmullRom.m_controlPointsTransformed = m_curveCatmullRom.m_controlPoints; + } + + void freezeTransform() + { + m_originKey.m_origin = m_origin; + m_originKey.write(&m_entity); + rotation_assign(m_rotationKey.m_rotation, m_rotation); + m_rotationKey.write(&m_entity); + m_curveNURBS.m_controlPoints = m_curveNURBS.m_controlPointsTransformed; + ControlPoints_write(m_curveNURBS.m_controlPoints, curve_Nurbs, m_entity); + m_curveCatmullRom.m_controlPoints = m_curveCatmullRom.m_controlPointsTransformed; + ControlPoints_write(m_curveCatmullRom.m_controlPoints, curve_CatmullRomSpline, m_entity); + } + + void transformChanged() + { + revertTransform(); + m_evaluateTransform(); + updateTransform(); + m_curveNURBS.curveChanged(); + m_curveCatmullRom.curveChanged(); + } + + typedef MemberCaller TransformChangedCaller; }; class Doom3GroupInstance : - public TargetableInstance, - public TransformModifier, - public Renderable, - public SelectionTestable, - public ComponentSelectionTestable, - public ComponentEditable, - public ComponentSnappable -{ - class TypeCasts - { - InstanceTypeCastTable m_casts; - public: - TypeCasts() - { - m_casts = TargetableInstance::StaticTypeCasts::instance().get(); - InstanceContainedCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceStaticCast::install(m_casts); - InstanceIdentityCast::install(m_casts); - } - InstanceTypeCastTable& get() - { - return m_casts; - } - }; - - Doom3Group& m_contained; - CurveEdit m_curveNURBS; - CurveEdit m_curveCatmullRom; - mutable AABB m_aabb_component; + public TargetableInstance, + public TransformModifier, + public Renderable, + public SelectionTestable, + public ComponentSelectionTestable, + public ComponentEditable, + public ComponentSnappable { + class TypeCasts { + InstanceTypeCastTable m_casts; + public: + TypeCasts() + { + m_casts = TargetableInstance::StaticTypeCasts::instance().get(); + InstanceContainedCast::install(m_casts); + InstanceStaticCast::install(m_casts); + InstanceStaticCast::install(m_casts); + InstanceStaticCast::install(m_casts); + InstanceStaticCast::install(m_casts); + InstanceStaticCast::install(m_casts); + InstanceStaticCast::install(m_casts); + InstanceIdentityCast::install(m_casts); + } + + InstanceTypeCastTable &get() + { + return m_casts; + } + }; + + Doom3Group &m_contained; + CurveEdit m_curveNURBS; + CurveEdit m_curveCatmullRom; + mutable AABB m_aabb_component; public: - typedef LazyStatic StaticTypeCasts; + typedef LazyStatic StaticTypeCasts; - Bounded& get(NullType) - { - return m_contained; - } + Bounded &get(NullType) + { + return m_contained; + } + + STRING_CONSTANT(Name, "Doom3GroupInstance"); + + Doom3GroupInstance(const scene::Path &path, scene::Instance *parent, Doom3Group &contained) : + TargetableInstance(path, parent, this, StaticTypeCasts::instance().get(), contained.getEntity(), *this), + TransformModifier(Doom3Group::TransformChangedCaller(contained), ApplyTransformCaller(*this)), + m_contained(contained), + m_curveNURBS(m_contained.m_curveNURBS.m_controlPointsTransformed, SelectionChangedComponentCaller(*this)), + m_curveCatmullRom(m_contained.m_curveCatmullRom.m_controlPointsTransformed, + SelectionChangedComponentCaller(*this)) + { + m_contained.instanceAttach(Instance::path()); + m_contained.m_curveNURBSChanged = m_contained.m_curveNURBS.connect(CurveEdit::CurveChangedCaller(m_curveNURBS)); + m_contained.m_curveCatmullRomChanged = m_contained.m_curveCatmullRom.connect( + CurveEdit::CurveChangedCaller(m_curveCatmullRom)); + + StaticRenderableConnectionLines::instance().attach(*this); + } + + ~Doom3GroupInstance() + { + StaticRenderableConnectionLines::instance().detach(*this); - STRING_CONSTANT(Name, "Doom3GroupInstance"); + m_contained.m_curveCatmullRom.disconnect(m_contained.m_curveCatmullRomChanged); + m_contained.m_curveNURBS.disconnect(m_contained.m_curveNURBSChanged); + m_contained.instanceDetach(Instance::path()); + } - Doom3GroupInstance(const scene::Path& path, scene::Instance* parent, Doom3Group& contained) : - TargetableInstance(path, parent, this, StaticTypeCasts::instance().get(), contained.getEntity(), *this), - TransformModifier(Doom3Group::TransformChangedCaller(contained), ApplyTransformCaller(*this)), - m_contained(contained), - m_curveNURBS(m_contained.m_curveNURBS.m_controlPointsTransformed, SelectionChangedComponentCaller(*this)), - m_curveCatmullRom(m_contained.m_curveCatmullRom.m_controlPointsTransformed, SelectionChangedComponentCaller(*this)) - { - m_contained.instanceAttach(Instance::path()); - m_contained.m_curveNURBSChanged = m_contained.m_curveNURBS.connect(CurveEdit::CurveChangedCaller(m_curveNURBS)); - m_contained.m_curveCatmullRomChanged = m_contained.m_curveCatmullRom.connect(CurveEdit::CurveChangedCaller(m_curveCatmullRom)); + void renderSolid(Renderer &renderer, const VolumeTest &volume) const + { + m_contained.renderSolid(renderer, volume, Instance::localToWorld(), getSelectable().isSelected()); - StaticRenderableConnectionLines::instance().attach(*this); - } - ~Doom3GroupInstance() - { - StaticRenderableConnectionLines::instance().detach(*this); + m_curveNURBS.renderComponentsSelected(renderer, volume, localToWorld()); + m_curveCatmullRom.renderComponentsSelected(renderer, volume, localToWorld()); + } - m_contained.m_curveCatmullRom.disconnect(m_contained.m_curveCatmullRomChanged); - m_contained.m_curveNURBS.disconnect(m_contained.m_curveNURBSChanged); - m_contained.instanceDetach(Instance::path()); - } - void renderSolid(Renderer& renderer, const VolumeTest& volume) const - { - m_contained.renderSolid(renderer, volume, Instance::localToWorld(), getSelectable().isSelected()); + void renderWireframe(Renderer &renderer, const VolumeTest &volume) const + { + m_contained.renderWireframe(renderer, volume, Instance::localToWorld(), getSelectable().isSelected(), + Instance::childBounds()); - m_curveNURBS.renderComponentsSelected(renderer, volume, localToWorld()); - m_curveCatmullRom.renderComponentsSelected(renderer, volume, localToWorld()); - } - void renderWireframe(Renderer& renderer, const VolumeTest& volume) const - { - m_contained.renderWireframe(renderer, volume, Instance::localToWorld(), getSelectable().isSelected(), Instance::childBounds()); + m_curveNURBS.renderComponentsSelected(renderer, volume, localToWorld()); + m_curveCatmullRom.renderComponentsSelected(renderer, volume, localToWorld()); + } - m_curveNURBS.renderComponentsSelected(renderer, volume, localToWorld()); - m_curveCatmullRom.renderComponentsSelected(renderer, volume, localToWorld()); - } - void renderComponents(Renderer& renderer, const VolumeTest& volume) const - { - if(GlobalSelectionSystem().ComponentMode() == SelectionSystem::eVertex) + void renderComponents(Renderer &renderer, const VolumeTest &volume) const { - m_curveNURBS.renderComponents(renderer, volume, localToWorld()); - m_curveCatmullRom.renderComponents(renderer, volume, localToWorld()); + if (GlobalSelectionSystem().ComponentMode() == SelectionSystem::eVertex) { + m_curveNURBS.renderComponents(renderer, volume, localToWorld()); + m_curveCatmullRom.renderComponents(renderer, volume, localToWorld()); + } } - } - void testSelect(Selector& selector, SelectionTest& test) - { - test.BeginMesh(localToWorld()); - SelectionIntersection best; + void testSelect(Selector &selector, SelectionTest &test) + { + test.BeginMesh(localToWorld()); + SelectionIntersection best; - m_contained.testSelect(selector, test, best); + m_contained.testSelect(selector, test, best); - if(best.valid()) + if (best.valid()) { + Selector_add(selector, getSelectable(), best); + } + } + + bool isSelectedComponents() const { - Selector_add(selector, getSelectable(), best); + return m_curveNURBS.isSelected() || m_curveCatmullRom.isSelected(); } - } - bool isSelectedComponents() const - { - return m_curveNURBS.isSelected() || m_curveCatmullRom.isSelected(); - } - void setSelectedComponents(bool selected, SelectionSystem::EComponentMode mode) - { - if(mode == SelectionSystem::eVertex) + void setSelectedComponents(bool selected, SelectionSystem::EComponentMode mode) { - m_curveNURBS.setSelected(selected); - m_curveCatmullRom.setSelected(selected); + if (mode == SelectionSystem::eVertex) { + m_curveNURBS.setSelected(selected); + m_curveCatmullRom.setSelected(selected); + } } - } - void testSelectComponents(Selector& selector, SelectionTest& test, SelectionSystem::EComponentMode mode) - { - if(mode == SelectionSystem::eVertex) + + void testSelectComponents(Selector &selector, SelectionTest &test, SelectionSystem::EComponentMode mode) { - test.BeginMesh(localToWorld()); - m_curveNURBS.testSelect(selector, test); - m_curveCatmullRom.testSelect(selector, test); + if (mode == SelectionSystem::eVertex) { + test.BeginMesh(localToWorld()); + m_curveNURBS.testSelect(selector, test); + m_curveCatmullRom.testSelect(selector, test); + } } - } - void transformComponents(const Matrix4& matrix) - { - if(m_curveNURBS.isSelected()) + void transformComponents(const Matrix4 &matrix) { - m_curveNURBS.transform(matrix); + if (m_curveNURBS.isSelected()) { + m_curveNURBS.transform(matrix); + } + if (m_curveCatmullRom.isSelected()) { + m_curveCatmullRom.transform(matrix); + } } - if(m_curveCatmullRom.isSelected()) + + const AABB &getSelectedComponentsBounds() const { - m_curveCatmullRom.transform(matrix); + m_aabb_component = AABB(); + m_curveNURBS.forEachSelected([&](const Vector3 &point) { + aabb_extend_by_point_safe(m_aabb_component, point); + }); + m_curveCatmullRom.forEachSelected([&](const Vector3 &point) { + aabb_extend_by_point_safe(m_aabb_component, point); + }); + return m_aabb_component; } - } - const AABB& getSelectedComponentsBounds() const - { - m_aabb_component = AABB(); - m_curveNURBS.forEachSelected(ControlPointAddBounds(m_aabb_component)); - m_curveCatmullRom.forEachSelected(ControlPointAddBounds(m_aabb_component)); - return m_aabb_component; - } - - void snapComponents(float snap) - { - if(m_curveNURBS.isSelected()) - { - m_curveNURBS.snapto(snap); - m_curveNURBS.write(curve_Nurbs, m_contained.getEntity()); + void snapComponents(float snap) + { + if (m_curveNURBS.isSelected()) { + m_curveNURBS.snapto(snap); + m_curveNURBS.write(curve_Nurbs, m_contained.getEntity()); + } + if (m_curveCatmullRom.isSelected()) { + m_curveCatmullRom.snapto(snap); + m_curveCatmullRom.write(curve_CatmullRomSpline, m_contained.getEntity()); + } } - if(m_curveCatmullRom.isSelected()) + + void evaluateTransform() { - m_curveCatmullRom.snapto(snap); - m_curveCatmullRom.write(curve_CatmullRomSpline, m_contained.getEntity()); + if (getType() == TRANSFORM_PRIMITIVE) { + m_contained.translate(getTranslation()); + m_contained.rotate(getRotation()); + } else { + transformComponents(calculateTransform()); + } } - } - void evaluateTransform() - { - if(getType() == TRANSFORM_PRIMITIVE) + void applyTransform() { - m_contained.translate(getTranslation()); - m_contained.rotate(getRotation()); + m_contained.revertTransform(); + evaluateTransform(); + m_contained.freezeTransform(); } - else + + typedef MemberCaller ApplyTransformCaller; + + void selectionChangedComponent(const Selectable &selectable) { - transformComponents(calculateTransform()); + GlobalSelectionSystem().getObserver(SelectionSystem::eComponent)(selectable); + GlobalSelectionSystem().onComponentSelection(*this, selectable); } - } - void applyTransform() - { - m_contained.revertTransform(); - evaluateTransform(); - m_contained.freezeTransform(); - } - typedef MemberCaller ApplyTransformCaller; - void selectionChangedComponent(const Selectable& selectable) - { - GlobalSelectionSystem().getObserver(SelectionSystem::eComponent)(selectable); - GlobalSelectionSystem().onComponentSelection(*this, selectable); - } - typedef MemberCaller1 SelectionChangedComponentCaller; + typedef MemberCaller SelectionChangedComponentCaller; }; class Doom3GroupNode : - public scene::Node::Symbiot, - public scene::Instantiable, - public scene::Cloneable, - public scene::Traversable::Observer -{ - class TypeCasts - { - NodeTypeCastTable m_casts; - public: - TypeCasts() - { - NodeStaticCast::install(m_casts); - NodeStaticCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - NodeContainedCast::install(m_casts); - } - NodeTypeCastTable& get() - { - return m_casts; - } - }; - - - scene::Node m_node; - InstanceSet m_instances; - Doom3Group m_contained; - - void construct() - { - m_contained.attach(this); - } - void destroy() - { - m_contained.detach(this); - } + public scene::Node::Symbiot, + public scene::Instantiable, + public scene::Cloneable, + public scene::Traversable::Observer { + class TypeCasts { + NodeTypeCastTable m_casts; + public: + TypeCasts() + { + NodeStaticCast::install(m_casts); + NodeStaticCast::install(m_casts); + NodeContainedCast::install(m_casts); + NodeContainedCast::install(m_casts); + NodeContainedCast::install(m_casts); + NodeContainedCast::install(m_casts); + NodeContainedCast::install(m_casts); + NodeContainedCast::install(m_casts); + NodeContainedCast::install(m_casts); + } + + NodeTypeCastTable &get() + { + return m_casts; + } + }; + + + scene::Node m_node; + InstanceSet m_instances; + Doom3Group m_contained; + + void construct() + { + m_contained.attach(this); + } + + void destroy() + { + m_contained.detach(this); + } + public: - typedef LazyStatic StaticTypeCasts; - - scene::Traversable& get(NullType) - { - return m_contained.getTraversable(); - } - Snappable& get(NullType) - { - return m_contained; - } - TransformNode& get(NullType) - { - return m_contained.getTransformNode(); - } - Entity& get(NullType) - { - return m_contained.getEntity(); - } - Nameable& get(NullType) - { - return m_contained.getNameable(); - } - Namespaced& get(NullType) - { - return m_contained.getNamespaced(); - } - ModelSkin& get(NullType) - { - return m_contained.getModelSkin(); - } - - Doom3GroupNode(EntityClass* eclass) : - m_node(this, this, StaticTypeCasts::instance().get()), - m_contained(eclass, m_node, InstanceSet::TransformChangedCaller(m_instances), InstanceSet::BoundsChangedCaller(m_instances), InstanceSetEvaluateTransform::Caller(m_instances)) - { - construct(); - } - Doom3GroupNode(const Doom3GroupNode& other) : - scene::Node::Symbiot(other), - scene::Instantiable(other), - scene::Cloneable(other), - scene::Traversable::Observer(other), - m_node(this, this, StaticTypeCasts::instance().get()), - m_contained(other.m_contained, m_node, InstanceSet::TransformChangedCaller(m_instances), InstanceSet::BoundsChangedCaller(m_instances), InstanceSetEvaluateTransform::Caller(m_instances)) - { - construct(); - } - ~Doom3GroupNode() - { - destroy(); - } - - void release() - { - delete this; - } - scene::Node& node() - { - return m_node; - } - - scene::Node& clone() const - { - return (new Doom3GroupNode(*this))->node(); - } - - void insert(scene::Node& child) - { - m_instances.insert(child); - } - void erase(scene::Node& child) - { - m_instances.erase(child); - } - - scene::Instance* create(const scene::Path& path, scene::Instance* parent) - { - return new Doom3GroupInstance(path, parent, m_contained); - } - void forEachInstance(const scene::Instantiable::Visitor& visitor) - { - m_instances.forEachInstance(visitor); - } - void insert(scene::Instantiable::Observer* observer, const scene::Path& path, scene::Instance* instance) - { - m_instances.insert(observer, path, instance); - } - scene::Instance* erase(scene::Instantiable::Observer* observer, const scene::Path& path) - { - return m_instances.erase(observer, path); - } + typedef LazyStatic StaticTypeCasts; + + scene::Traversable &get(NullType) + { + return m_contained.getTraversable(); + } + + Snappable &get(NullType) + { + return m_contained; + } + + TransformNode &get(NullType) + { + return m_contained.getTransformNode(); + } + + Entity &get(NullType) + { + return m_contained.getEntity(); + } + + Nameable &get(NullType) + { + return m_contained.getNameable(); + } + + Namespaced &get(NullType) + { + return m_contained.getNamespaced(); + } + + ModelSkin &get(NullType) + { + return m_contained.getModelSkin(); + } + + Doom3GroupNode(EntityClass *eclass) : + m_node(this, this, StaticTypeCasts::instance().get()), + m_contained(eclass, m_node, InstanceSet::TransformChangedCaller(m_instances), + InstanceSet::BoundsChangedCaller(m_instances), + InstanceSetEvaluateTransform::Caller(m_instances)) + { + construct(); + } + + Doom3GroupNode(const Doom3GroupNode &other) : + scene::Node::Symbiot(other), + scene::Instantiable(other), + scene::Cloneable(other), + scene::Traversable::Observer(other), + m_node(this, this, StaticTypeCasts::instance().get()), + m_contained(other.m_contained, m_node, InstanceSet::TransformChangedCaller(m_instances), + InstanceSet::BoundsChangedCaller(m_instances), + InstanceSetEvaluateTransform::Caller(m_instances)) + { + construct(); + } + + ~Doom3GroupNode() + { + destroy(); + } + + void release() + { + delete this; + } + + scene::Node &node() + { + return m_node; + } + + scene::Node &clone() const + { + return (new Doom3GroupNode(*this))->node(); + } + + void insert(scene::Node &child) + { + m_instances.insert(child); + } + + void erase(scene::Node &child) + { + m_instances.erase(child); + } + + scene::Instance *create(const scene::Path &path, scene::Instance *parent) + { + return new Doom3GroupInstance(path, parent, m_contained); + } + + void forEachInstance(const scene::Instantiable::Visitor &visitor) + { + m_instances.forEachInstance(visitor); + } + + void insert(scene::Instantiable::Observer *observer, const scene::Path &path, scene::Instance *instance) + { + m_instances.insert(observer, path, instance); + } + + scene::Instance *erase(scene::Instantiable::Observer *observer, const scene::Path &path) + { + return m_instances.erase(observer, path); + } }; void Doom3Group_construct() { - CurveEdit::Type::instance().m_controlsShader = GlobalShaderCache().capture("$POINT"); - CurveEdit::Type::instance().m_selectedShader = GlobalShaderCache().capture("$SELPOINT"); + CurveEdit::Type::instance().m_controlsShader = GlobalShaderCache().capture("$POINT"); + CurveEdit::Type::instance().m_selectedShader = GlobalShaderCache().capture("$SELPOINT"); } void Doom3Group_destroy() { - GlobalShaderCache().release("$SELPOINT"); - GlobalShaderCache().release("$POINT"); + GlobalShaderCache().release("$SELPOINT"); + GlobalShaderCache().release("$POINT"); } -scene::Node& New_Doom3Group(EntityClass* eclass) +scene::Node &New_Doom3Group(EntityClass *eclass) { - return (new Doom3GroupNode(eclass))->node(); + return (new Doom3GroupNode(eclass))->node(); }