-const AABB& localAABB() const {
- return m_aabb_light;
-}
-
-
-mutable Matrix4 m_projectionOrientation;
-
-void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld, bool selected ) const {
- renderer.SetState( m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly );
- renderer.SetState( m_colour.state(), Renderer::eFullMaterials );
- renderer.addRenderable( *this, localToWorld );
-
- if ( selected && g_lightRadii && string_empty( m_entity.getKeyValue( "target" ) ) ) {
- if ( renderer.getStyle() == Renderer::eFullMaterials ) {
- renderer.SetState( RenderLightRadiiFill::m_state, Renderer::eFullMaterials );
- renderer.Highlight( Renderer::ePrimitive, false );
- renderer.addRenderable( m_radii_fill, localToWorld );
- }
- else
- {
- renderer.addRenderable( m_radii_wire, localToWorld );
- }
- }
-
- renderer.SetState( m_entity.getEntityClass().m_state_wire, Renderer::eFullMaterials );
-
- if ( g_lightType == LIGHTTYPE_DOOM3 && selected ) {
- if ( isProjected() ) {
- projection();
- m_projectionOrientation = rotation();
- vector4_to_vector3( m_projectionOrientation.t() ) = localAABB().origin;
- renderer.addRenderable( m_renderProjection, m_projectionOrientation );
- }
- else
- {
- updateLightRadiiBox();
- renderer.addRenderable( m_radii_box, localToWorld );
- }
-
- //draw the center of the light
- if ( m_doom3Radius.m_useCenterKey ) {
- renderer.Highlight( Renderer::ePrimitive, false );
- renderer.Highlight( Renderer::eFace, false );
- renderer.SetState( m_render_center.m_state, Renderer::eFullMaterials );
- renderer.SetState( m_render_center.m_state, Renderer::eWireframeOnly );
- renderer.addRenderable( m_render_center, localToWorld );
- }
- }
-}
-void renderWireframe( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld, bool selected ) const {
- renderSolid( renderer, volume, localToWorld, selected );
- if ( g_showNames ) {
- renderer.addRenderable( m_renderName, localToWorld );
- }
-}
-
-void testSelect( Selector& selector, SelectionTest& test, const Matrix4& localToWorld ){
- test.BeginMesh( localToWorld );
-
- SelectionIntersection best;
- aabb_testselect( m_aabb_light, test, best );
- if ( best.valid() ) {
- selector.addIntersection( best );
- }
-}
-
-void translate( const Vector3& translation ){
- m_aabb_light.origin = origin_translated( m_aabb_light.origin, translation );
-}
-void rotate( const Quaternion& rotation ){
- rotation_rotate( m_rotation, rotation );
-}
-void snapto( float snap ){
- if ( g_lightType == LIGHTTYPE_DOOM3 && !m_useLightOrigin && !m_traverse.empty() ) {
- m_useLightOrigin = true;
- m_lightOrigin = m_originKey.m_origin;
- }
-
- if ( m_useLightOrigin ) {
- m_lightOrigin = origin_snapped( m_lightOrigin, snap );
- writeLightOrigin();
- }
- else
- {
- m_originKey.m_origin = origin_snapped( m_originKey.m_origin, snap );
- 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(){
- if ( g_lightType == LIGHTTYPE_DOOM3 && !m_useLightOrigin && !m_traverse.empty() ) {
- m_useLightOrigin = true;
- }
-
- if ( m_useLightOrigin ) {
- m_lightOrigin = m_aabb_light.origin;
- writeLightOrigin();
- }
- else
- {
- m_originKey.m_origin = m_aabb_light.origin;
- m_originKey.write( &m_entity );
- }
-
- if ( g_lightType == LIGHTTYPE_DOOM3 ) {
- if ( !m_useLightRotation && !m_traverse.empty() ) {
- m_useLightRotation = true;
- }
-
- if ( m_useLightRotation ) {
- rotation_assign( m_lightRotation, m_rotation );
- write_rotation( m_lightRotation, &m_entity, "light_rotation" );
- }
-
- 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(){
- revertTransform();
- m_evaluateTransform();
- updateOrigin();
-}
-typedef MemberCaller<Light, void(), &Light::transformChanged> TransformChangedCaller;
-
-mutable Matrix4 m_localPivot;
-const Matrix4& getLocalPivot() const {
- m_localPivot = rotation_toMatrix( m_rotation );
- vector4_to_vector3( m_localPivot.t() ) = m_aabb_light.origin;
- return m_localPivot;
-}
-
-void setLightChangedCallback( const Callback<void()>& callback ){
- m_doom3Radius.m_changed = callback;
-}
-
-const AABB& aabb() const {
- m_doom3AABB = AABB( m_aabb_light.origin, m_doom3Radius.m_radiusTransformed );
- return m_doom3AABB;
-}
-bool testAABB( const AABB& other ) const {
- if ( isProjected() ) {
- Matrix4 transform = rotation();
- vector4_to_vector3( transform.t() ) = localAABB().origin;
- projection();
- Frustum frustum( frustum_transformed( m_doom3Frustum, transform ) );
- return frustum_test_aabb( frustum, other ) != c_volumeOutside;
- }
- // test against an AABB which contains the rotated bounds of this light.
- const AABB& bounds = aabb();
- return aabb_intersects_aabb( other, AABB(
- bounds.origin,
- Vector3(
- static_cast<float>( fabs( m_rotation[0] * bounds.extents[0] )
- + fabs( m_rotation[3] * bounds.extents[1] )
- + fabs( m_rotation[6] * bounds.extents[2] ) ),
- static_cast<float>( fabs( m_rotation[1] * bounds.extents[0] )
- + fabs( m_rotation[4] * bounds.extents[1] )
- + fabs( m_rotation[7] * bounds.extents[2] ) ),
- static_cast<float>( fabs( m_rotation[2] * bounds.extents[0] )
- + fabs( m_rotation[5] * bounds.extents[1] )
- + fabs( m_rotation[8] * bounds.extents[2] ) )
- )
- ) );
-}
-
-const Matrix4& rotation() const {
- m_doom3Rotation = rotation_toMatrix( m_rotation );
- return m_doom3Rotation;
-}
-const Vector3& offset() const {
- return m_doom3Radius.m_center;
-}
-const Vector3& colour() const {
- return m_colour.m_colour;
-}
-
-bool isProjected() const {
- return m_useLightTarget && m_useLightUp && m_useLightRight;
-}
-void projectionChanged(){
- m_doom3ProjectionChanged = true;
- m_doom3Radius.m_changed();
- SceneChangeNotify();
-}
-
-const Matrix4& projection() const {
- if ( !m_doom3ProjectionChanged ) {
- return m_doom3Projection;
- }
- m_doom3ProjectionChanged = false;
- m_doom3Projection = g_matrix4_identity;
- matrix4_translate_by_vec3( m_doom3Projection, Vector3( 0.5f, 0.5f, 0 ) );
- matrix4_scale_by_vec3( m_doom3Projection, Vector3( 0.5f, 0.5f, 1 ) );
+ const AABB &localAABB() const
+ {
+ return m_aabb_light;
+ }
+
+
+ mutable Matrix4 m_projectionOrientation;
+
+ void renderSolid(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld, bool selected) const
+ {
+ renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly);
+ renderer.SetState(m_colour.state(), Renderer::eFullMaterials);
+ renderer.addRenderable(*this, localToWorld);
+
+ if (selected && g_lightRadii && string_empty(m_entity.getKeyValue("target"))) {
+ if (renderer.getStyle() == Renderer::eFullMaterials) {
+ renderer.SetState(RenderLightRadiiFill::m_state, Renderer::eFullMaterials);
+ renderer.Highlight(Renderer::ePrimitive, false);
+ renderer.addRenderable(m_radii_fill, localToWorld);
+ } else {
+ renderer.addRenderable(m_radii_wire, localToWorld);
+ }
+ }
+
+ renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eFullMaterials);
+
+ if (g_lightType == LIGHTTYPE_DOOM3 && selected) {
+ if (isProjected()) {
+ projection();
+ m_projectionOrientation = rotation();
+ vector4_to_vector3(m_projectionOrientation.t()) = localAABB().origin;
+ renderer.addRenderable(m_renderProjection, m_projectionOrientation);
+ } else {
+ updateLightRadiiBox();
+ renderer.addRenderable(m_radii_box, localToWorld);
+ }
+
+ //draw the center of the light
+ if (m_doom3Radius.m_useCenterKey) {
+ renderer.Highlight(Renderer::ePrimitive, false);
+ renderer.Highlight(Renderer::eFace, false);
+ renderer.SetState(m_render_center.m_state, Renderer::eFullMaterials);
+ renderer.SetState(m_render_center.m_state, Renderer::eWireframeOnly);
+ renderer.addRenderable(m_render_center, localToWorld);
+ }
+ }
+ }
+
+ void renderWireframe(Renderer &renderer, const VolumeTest &volume, const Matrix4 &localToWorld, bool selected) const
+ {
+ renderSolid(renderer, volume, localToWorld, selected);
+ if (g_showNames) {
+ renderer.addRenderable(m_renderName, localToWorld);
+ }
+ }
+
+ void testSelect(Selector &selector, SelectionTest &test, const Matrix4 &localToWorld)
+ {
+ test.BeginMesh(localToWorld);
+
+ SelectionIntersection best;
+ aabb_testselect(m_aabb_light, test, best);
+ if (best.valid()) {
+ selector.addIntersection(best);
+ }
+ }
+
+ void translate(const Vector3 &translation)
+ {
+ m_aabb_light.origin = origin_translated(m_aabb_light.origin, translation);
+ }
+
+ void rotate(const Quaternion &rotation)
+ {
+ rotation_rotate(m_rotation, rotation);
+ }
+
+ void snapto(float snap)
+ {
+ if (g_lightType == LIGHTTYPE_DOOM3 && !m_useLightOrigin && !m_traverse.empty()) {
+ m_useLightOrigin = true;
+ m_lightOrigin = m_originKey.m_origin;
+ }
+
+ if (m_useLightOrigin) {
+ m_lightOrigin = origin_snapped(m_lightOrigin, snap);
+ writeLightOrigin();
+ } else {
+ m_originKey.m_origin = origin_snapped(m_originKey.m_origin, snap);
+ 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()
+ {
+ if (g_lightType == LIGHTTYPE_DOOM3 && !m_useLightOrigin && !m_traverse.empty()) {
+ m_useLightOrigin = true;
+ }
+
+ if (m_useLightOrigin) {
+ m_lightOrigin = m_aabb_light.origin;
+ writeLightOrigin();
+ } else {
+ m_originKey.m_origin = m_aabb_light.origin;
+ m_originKey.write(&m_entity);
+ }
+
+ if (g_lightType == LIGHTTYPE_DOOM3) {
+ if (!m_useLightRotation && !m_traverse.empty()) {
+ m_useLightRotation = true;
+ }
+
+ if (m_useLightRotation) {
+ rotation_assign(m_lightRotation, m_rotation);
+ write_rotation(m_lightRotation, &m_entity, "light_rotation");
+ }
+
+ 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()
+ {
+ revertTransform();
+ m_evaluateTransform();
+ updateOrigin();
+ }
+
+ typedef MemberCaller<Light, void(), &Light::transformChanged> TransformChangedCaller;
+
+ mutable Matrix4 m_localPivot;
+
+ const Matrix4 &getLocalPivot() const
+ {
+ m_localPivot = rotation_toMatrix(m_rotation);
+ vector4_to_vector3(m_localPivot.t()) = m_aabb_light.origin;
+ return m_localPivot;
+ }
+
+ void setLightChangedCallback(const Callback<void()> &callback)
+ {
+ m_doom3Radius.m_changed = callback;
+ }
+
+ const AABB &aabb() const
+ {
+ m_doom3AABB = AABB(m_aabb_light.origin, m_doom3Radius.m_radiusTransformed);
+ return m_doom3AABB;
+ }
+
+ bool testAABB(const AABB &other) const
+ {
+ if (isProjected()) {
+ Matrix4 transform = rotation();
+ vector4_to_vector3(transform.t()) = localAABB().origin;
+ projection();
+ Frustum frustum(frustum_transformed(m_doom3Frustum, transform));
+ return frustum_test_aabb(frustum, other) != c_volumeOutside;
+ }
+ // test against an AABB which contains the rotated bounds of this light.
+ const AABB &bounds = aabb();
+ return aabb_intersects_aabb(other, AABB(
+ bounds.origin,
+ Vector3(
+ static_cast<float>( fabs(m_rotation[0] * bounds.extents[0])
+ + fabs(m_rotation[3] * bounds.extents[1])
+ + fabs(m_rotation[6] * bounds.extents[2])),
+ static_cast<float>( fabs(m_rotation[1] * bounds.extents[0])
+ + fabs(m_rotation[4] * bounds.extents[1])
+ + fabs(m_rotation[7] * bounds.extents[2])),
+ static_cast<float>( fabs(m_rotation[2] * bounds.extents[0])
+ + fabs(m_rotation[5] * bounds.extents[1])
+ + fabs(m_rotation[8] * bounds.extents[2]))
+ )
+ ));
+ }
+
+ const Matrix4 &rotation() const
+ {
+ m_doom3Rotation = rotation_toMatrix(m_rotation);
+ return m_doom3Rotation;
+ }
+
+ const Vector3 &offset() const
+ {
+ return m_doom3Radius.m_center;
+ }
+
+ const Vector3 &colour() const
+ {
+ return m_colour.m_colour;
+ }
+
+ bool isProjected() const
+ {
+ return m_useLightTarget && m_useLightUp && m_useLightRight;
+ }
+
+ void projectionChanged()
+ {
+ m_doom3ProjectionChanged = true;
+ m_doom3Radius.m_changed();
+ SceneChangeNotify();
+ }
+
+ const Matrix4 &projection() const
+ {
+ if (!m_doom3ProjectionChanged) {
+ return m_doom3Projection;
+ }
+ m_doom3ProjectionChanged = false;
+ m_doom3Projection = g_matrix4_identity;
+ matrix4_translate_by_vec3(m_doom3Projection, Vector3(0.5f, 0.5f, 0));
+ matrix4_scale_by_vec3(m_doom3Projection, Vector3(0.5f, 0.5f, 1));