#include "render.h"
#include "stringio.h"
#include "traverselib.h"
+#include "dragplanes.h"
#include "targetable.h"
#include "origin.h"
typedef MemberCaller1<LightRadii, const char*, &LightRadii::flagsChanged> FlagsChangedCaller;
};
-const Vector3 c_defaultDoom3LightRadius = Vector3(300, 300, 300);
class Doom3LightRadius
{
public:
+ Vector3 m_defaultRadius;
Vector3 m_radius;
+ Vector3 m_radiusTransformed;
Vector3 m_center;
Callback m_changed;
bool m_useCenterKey;
- Doom3LightRadius() : m_radius(c_defaultDoom3LightRadius), m_center(0, 0, 0), m_useCenterKey(false)
+ Doom3LightRadius(const char* defaultRadius) : m_defaultRadius(300, 300, 300), m_center(0, 0, 0), m_useCenterKey(false)
{
+ if(!string_parse_vector3(defaultRadius, m_defaultRadius))
+ {
+ globalErrorStream() << "Doom3LightRadius: failed to parse default light radius\n";
+ }
+ m_radius = m_defaultRadius;
}
void lightRadiusChanged(const char* value)
{
if(!string_parse_vector3(value, m_radius))
{
- m_radius = c_defaultDoom3LightRadius;
+ m_radius = m_defaultRadius;
}
+ 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_named(m_entity),
m_nameKeys(m_entity),
m_funcStaticOrigin(m_traverse, m_originKey.m_origin),
+ m_doom3Radius(EntityClass_valueForKey(m_entity.getEntityClass(), "light_radius")),
m_radii_wire(m_radii, m_aabb_light.origin),
m_radii_fill(m_radii, m_aabb_light.origin),
m_radii_box(m_aabb_light.origin),
m_named(m_entity),
m_nameKeys(m_entity),
m_funcStaticOrigin(m_traverse, m_originKey.m_origin),
+ m_doom3Radius(EntityClass_valueForKey(m_entity.getEntityClass(), "light_radius")),
m_radii_wire(m_radii, m_aabb_light.origin),
m_radii_fill(m_radii, m_aabb_light.origin),
m_radii_box(m_aabb_light.origin),
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;
+ 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();
+ m_contained.setLightRadius(m_dragPlanes.evaluateResize(getTranslation(), rotation()));
+ }
}
void applyTransform()
{