This is the changelog for developers, != changelog for the end user
that we distribute with the binaries. (see changelog)
+28/02/2006
+namespace, SPoG
+- Added drag-resizing for doom3/quake4 light_radius boxes.
+
25/02/2006
SPoG
- Fixed objects sometimes dissappearing when at high zoom level in Ortho views.
#include "math/aabb.h"
#include "math/line.h"
+// local must be a pure rotation
+inline Vector3 translation_to_local(const Vector3& translation, const Matrix4& local)
+{
+ return matrix4_get_translation_vec3(
+ matrix4_multiplied_by_matrix4(
+ matrix4_translated_by_vec3(matrix4_transposed(local), translation),
+ local
+ )
+ );
+}
+
+// local must be a pure rotation
+inline Vector3 translation_from_local(const Vector3& translation, const Matrix4& local)
+{
+ return matrix4_get_translation_vec3(
+ matrix4_multiplied_by_matrix4(
+ matrix4_translated_by_vec3(local, translation),
+ matrix4_transposed(local)
+ )
+ );
+}
+
class DragPlanes
{
public:
m_selectable_top.setSelected(selected);
m_selectable_bottom.setSelected(selected);
}
- void selectPlanes(const AABB& aabb, Selector& selector, SelectionTest& test, const PlaneCallback& selectedPlaneCallback)
+ void selectPlanes(const AABB& aabb, Selector& selector, SelectionTest& test, const PlaneCallback& selectedPlaneCallback, const Matrix4& rotation = g_matrix4_identity)
{
Line line(test.getNear(), test.getFar());
Vector3 corners[8];
- aabb_corners(aabb, corners);
+ aabb_corners_oriented(aabb, rotation, corners);
+
Plane3 planes[6];
- aabb_planes(aabb, planes);
+ aabb_planes_oriented(aabb, rotation, planes);
for(Vector3* i = corners; i != corners + 8; ++i)
{
&& vector3_dot(planes[5].normal(), corners[7]) > 0)
{
Selector_add(selector, m_selectable_bottom);
- //globalOutputStream() << "bottom\n";
selectedPlaneCallback(planes[5]);
+ //globalOutputStream() << "bottom\n";
}
m_bounds = aabb;
}
- void selectReversedPlanes(const AABB& aabb, Selector& selector, const SelectedPlanes& selectedPlanes)
+ void selectReversedPlanes(const AABB& aabb, Selector& selector, const SelectedPlanes& selectedPlanes, const Matrix4& rotation = g_matrix4_identity)
{
Plane3 planes[6];
- aabb_planes(aabb, planes);
+ aabb_planes_oriented(aabb, rotation, planes);
if(selectedPlanes.contains(plane3_flipped(planes[0])))
{
Selector_add(selector, m_selectable_bottom);
}
}
- Matrix4 evaluateTransform(const Vector3& translation) const
+ AABB evaluateResize(const Vector3& translation) const
{
Vector3 min = m_bounds.origin - m_bounds.extents;
Vector3 max = m_bounds.origin + m_bounds.extents;
- Vector3 origin = m_bounds.origin;
- Vector3 extents = m_bounds.extents;
- if(extents[0] != 0)
+ if(m_bounds.extents[0] != 0)
{
if(m_selectable_right.isSelected())
{
//globalOutputStream() << "moving left\n";
}
}
- if(extents[1] != 0)
+ if(m_bounds.extents[1] != 0)
{
if(m_selectable_front.isSelected())
{
//globalOutputStream() << "moving back\n";
}
}
- if(extents[2] != 0)
+ if(m_bounds.extents[2] != 0)
{
if(m_selectable_top.isSelected())
{
}
}
- Vector3 originTransformed(vector3_mid(min, max));
- Vector3 scale(vector3_scaled(vector3_subtracted(max, min), 0.5));
-
- if(extents[0] != 0)
- {
- scale[0] /= extents[0];
- }
- else
- {
- scale[0] = 1;
- }
- if(extents[1] != 0)
- {
- scale[1] /= extents[1];
- }
- else
- {
- scale[1] = 1;
- }
- if(extents[2] != 0)
- {
- scale[2] /= extents[2];
- }
- else
- {
- scale[2] = 1;
- }
+ return AABB(vector3_mid(min, max), vector3_scaled(vector3_subtracted(max, min), 0.5));
+ }
+ Matrix4 evaluateTransform(const Vector3& translation) const
+ {
+ AABB aabb(evaluateResize(translation));
+ Vector3 scale(
+ m_bounds.extents[0] != 0 ? aabb.extents[0] / m_bounds.extents[0] : 1,
+ m_bounds.extents[1] != 0 ? aabb.extents[1] / m_bounds.extents[1] : 1,
+ m_bounds.extents[2] != 0 ? aabb.extents[2] / m_bounds.extents[2] : 1
+ );
- Matrix4 matrix(matrix4_translation_for_vec3(originTransformed - origin));
- matrix4_pivoted_scale_by_vec3(matrix, scale, origin);
+ Matrix4 matrix(matrix4_translation_for_vec3(aabb.origin - m_bounds.origin));
+ matrix4_pivoted_scale_by_vec3(matrix, scale, m_bounds.origin);
return matrix;
- }
+ }
};
#endif
corners[7] = Vector3(min[0], min[1], min[2]);
}
+inline void aabb_corners_oriented(const AABB& aabb, const Matrix4& rotation, Vector3 corners[8])
+{
+ Vector3 x = Vector3(rotation.x()) * aabb.extents.x();
+ Vector3 y = Vector3(rotation.y()) * aabb.extents.y();
+ Vector3 z = Vector3(rotation.z()) * aabb.extents.z();
+
+ corners[0] = aabb.origin + -x + y + z;
+ corners[1] = aabb.origin + x + y + z;
+ corners[2] = aabb.origin + x + -y + z;
+ corners[3] = aabb.origin + -x + -y + z;
+ corners[4] = aabb.origin + -x + y + -z;
+ corners[5] = aabb.origin + x + y + -z;
+ corners[6] = aabb.origin + x + -y + -z;
+ corners[7] = aabb.origin + -x + -y + -z;
+}
+
inline void aabb_planes(const AABB& aabb, Plane3 planes[6])
{
planes[0] = Plane3(g_vector3_axes[0], aabb.origin[0] + aabb.extents[0]);
planes[5] = Plane3(vector3_negated(g_vector3_axes[2]), -(aabb.origin[2] - aabb.extents[2]));
}
+inline void aabb_planes_oriented(const AABB& aabb, const Matrix4& rotation, Plane3 planes[6])
+{
+ double x = vector3_dot(Vector3(rotation.x()), aabb.origin);
+ double y = vector3_dot(Vector3(rotation.y()), aabb.origin);
+ double z = vector3_dot(Vector3(rotation.z()), aabb.origin);
+
+ planes[0] = Plane3(Vector3(rotation.x()), x + aabb.extents[0]);
+ planes[1] = Plane3(-Vector3(rotation.x()), -(x - aabb.extents[0]));
+ planes[2] = Plane3(Vector3(rotation.y()), y + aabb.extents[1]);
+ planes[3] = Plane3(-Vector3(rotation.y()), -(y - aabb.extents[1]));
+ planes[4] = Plane3(Vector3(rotation.z()), z + aabb.extents[2]);
+ planes[5] = Plane3(-Vector3(rotation.z()), -(z - aabb.extents[2]));
+}
+
const Vector3 aabb_normals[6] = {
Vector3( 1, 0, 0 ),
Vector3( 0, 1, 0 ),
{
return BasicVector3<Element>(-self.x(), -self.y(), -self.z());
}
+template<typename Element>
+inline BasicVector3<Element> operator-(const BasicVector3<Element>& self)
+{
+ return vector3_negated(self);
+}
template<typename Element>
inline void vector3_negate(BasicVector3<Element>& self)
#include "render.h"
#include "stringio.h"
#include "traverselib.h"
+#include "dragplanes.h"
#include "targetable.h"
#include "origin.h"
{
public:
Vector3 m_radius;
+ Vector3 m_radiusTransformed;
Vector3 m_center;
Callback m_changed;
bool m_useCenterKey;
{
m_radius = c_defaultDoom3LightRadius;
}
+ m_radiusTransformed = m_radius;
m_changed();
SceneChangeNotify();
}
void updateLightRadiiBox() const
{
const Matrix4& rotation = rotation_toMatrix(m_rotation);
- aabb_corners(AABB(Vector3(0, 0, 0), m_doom3Radius.m_radius), m_radii_box.m_points);
+ aabb_corners(AABB(Vector3(0, 0, 0), m_doom3Radius.m_radiusTransformed), m_radii_box.m_points);
matrix4_transform_point(rotation, m_radii_box.m_points[0]);
vector3_add(m_radii_box.m_points[0], m_aabb_light.origin);
matrix4_transform_point(rotation, m_radii_box.m_points[1]);
m_originKey.write(&m_entity);
}
}
+ void setLightRadius(const AABB& aabb)
+ {
+ m_aabb_light.origin = aabb.origin;
+ m_doom3Radius.m_radiusTransformed = aabb.extents;
+ }
+ void transformLightRadius(const Matrix4& transform)
+ {
+ matrix4_transform_point(transform, m_aabb_light.origin);
+ }
void revertTransform()
{
m_aabb_light.origin = m_useLightOrigin ? m_lightOrigin : m_originKey.m_origin;
rotation_assign(m_rotation, m_useLightRotation ? m_lightRotation : m_rotationKey.m_rotation);
+ m_doom3Radius.m_radiusTransformed = m_doom3Radius.m_radius;
}
void freezeTransform()
{
rotation_assign(m_rotationKey.m_rotation, m_rotation);
write_rotation(m_rotationKey.m_rotation, &m_entity);
+
+ m_doom3Radius.m_radius = m_doom3Radius.m_radiusTransformed;
+ if(m_doom3Radius.m_radius == c_defaultDoom3LightRadius)
+ {
+ m_entity.setKeyValue("light_radius", "");
+ }
+ else
+ {
+ write_origin(m_doom3Radius.m_radius, &m_entity, "light_radius");
+ }
}
}
void transformChanged()
const AABB& aabb() const
{
- m_doom3AABB = AABB(m_aabb_light.origin, m_doom3Radius.m_radius);
+ m_doom3AABB = AABB(m_aabb_light.origin, m_doom3Radius.m_radiusTransformed);
return m_doom3AABB;
}
bool testAABB(const AABB& other) const
public TransformModifier,
public Renderable,
public SelectionTestable,
- public RendererLight
+ public RendererLight,
+ public PlaneSelectable,
+ public ComponentSelectionTestable
{
class TypeCasts
{
InstanceStaticCast<LightInstance, Renderable>::install(m_casts);
InstanceStaticCast<LightInstance, SelectionTestable>::install(m_casts);
InstanceStaticCast<LightInstance, Transformable>::install(m_casts);
+ InstanceStaticCast<LightInstance, PlaneSelectable>::install(m_casts);
+ InstanceStaticCast<LightInstance, ComponentSelectionTestable>::install(m_casts);
InstanceIdentityCast<LightInstance>::install(m_casts);
}
InstanceTypeCastTable& get()
};
Light& m_contained;
+ DragPlanes m_dragPlanes;// dragplanes for lightresizing using mousedrag
public:
typedef LazyStatic<TypeCasts> StaticTypeCasts;
LightInstance(const scene::Path& path, scene::Instance* parent, Light& contained) :
TargetableInstance(path, parent, this, StaticTypeCasts::instance().get(), contained.getEntity(), *this),
TransformModifier(Light::TransformChangedCaller(contained), ApplyTransformCaller(*this)),
- m_contained(contained)
+ m_contained(contained),
+ m_dragPlanes(SelectedChangedComponentCaller(*this))
{
m_contained.instanceAttach(Instance::path());
m_contained.testSelect(selector, test, Instance::localToWorld());
}
+ void selectPlanes(Selector& selector, SelectionTest& test, const PlaneCallback& selectedPlaneCallback)
+ {
+ test.BeginMesh(localToWorld());
+ m_dragPlanes.selectPlanes(m_contained.aabb(), selector, test, selectedPlaneCallback, rotation());
+ }
+ void selectReversedPlanes(Selector& selector, const SelectedPlanes& selectedPlanes)
+ {
+ m_dragPlanes.selectReversedPlanes(m_contained.aabb(), selector, selectedPlanes, rotation());
+ }
+
+ bool isSelectedComponents() const
+ {
+ return m_dragPlanes.isSelected();
+ }
+ void setSelectedComponents(bool select, SelectionSystem::EComponentMode mode)
+ {
+ if(mode == SelectionSystem::eFace)
+ {
+ m_dragPlanes.setSelected(false);
+ }
+ }
+ void testSelectComponents(Selector& selector, SelectionTest& test, SelectionSystem::EComponentMode mode)
+ {
+ }
+
+ void selectedChangedComponent(const Selectable& selectable)
+ {
+ GlobalSelectionSystem().getObserver(SelectionSystem::eComponent)(selectable);
+ GlobalSelectionSystem().onComponentSelection(*this, selectable);
+ }
+ typedef MemberCaller1<LightInstance, const Selectable&, &LightInstance::selectedChangedComponent> SelectedChangedComponentCaller;
+
void evaluateTransform()
{
if(getType() == TRANSFORM_PRIMITIVE)
m_contained.translate(getTranslation());
m_contained.rotate(getRotation());
}
+ else
+ {
+ //globalOutputStream() << getTranslation() << "\n";
+
+ m_dragPlanes.m_bounds = m_contained.aabb();
+ AABB aabb(m_dragPlanes.evaluateResize(translation_to_local(getTranslation(), rotation())));
+ aabb.origin = m_contained.aabb().origin + translation_from_local(aabb.origin - m_contained.aabb().origin, rotation());
+
+ m_contained.setLightRadius(aabb);
+ }
}
void applyTransform()
{
void XYWnd::SetScale(float f)
{
m_fScale = f;
+ updateProjection();
updateModelview();
XYWnd_Update(*this);
}
Map_addValidCallback(g_map, DeferredDrawOnMapValidChangedCaller(m_deferredDraw));
+ updateProjection();
updateModelview();
AddSceneChangeCallback(ReferenceCaller<XYWnd, &XYWnd_Update>(*this));
{
m_projection[0] = 1.0f / static_cast<float>(m_nWidth / 2);
m_projection[5] = 1.0f / static_cast<float>(m_nHeight / 2);
- m_projection[10] = 1.0f / g_MaxWorldCoord;
+ m_projection[10] = 1.0f / (g_MaxWorldCoord * m_fScale);
m_projection[12] = 0.0f;
m_projection[13] = 0.0f;
m_view.Construct(m_projection, m_modelview, m_nWidth, m_nHeight);
}
+// note: modelview matrix must have a uniform scale, otherwise strange things happen when rendering the rotation manipulator.
void XYWnd::updateModelview()
{
int nDim1 = (m_viewType == YZ) ? 1 : 0;
// translation
m_modelview[12] = -m_vOrigin[nDim1] * m_fScale;
m_modelview[13] = -m_vOrigin[nDim2] * m_fScale;
- m_modelview[14] = static_cast<float>(g_MaxWorldCoord);
+ m_modelview[14] = g_MaxWorldCoord * m_fScale;
// axis base
switch(m_viewType)
m_modelview[8] = 0;
m_modelview[9] = 0;
- m_modelview[10] = -1.0;
+ m_modelview[10] = -m_fScale;
break;
case XZ:
m_modelview[0] = m_fScale;
m_modelview[4] = 0;
m_modelview[5] = 0;
- m_modelview[6] = 1.0;
+ m_modelview[6] = m_fScale;
m_modelview[8] = 0;
m_modelview[9] = m_fScale;
case YZ:
m_modelview[0] = 0;
m_modelview[1] = 0;
- m_modelview[2] = -1.0;
+ m_modelview[2] = -m_fScale;
m_modelview[4] = m_fScale;
m_modelview[5] = 0;