2 Copyright (C) 2001-2006, William Joseph.
5 This file is part of GtkRadiant.
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "nullmodel.h"
24 #include "debugging/debugging.h"
26 #include "iscenegraph.h"
28 #include "iselection.h"
31 #include "ireference.h"
34 #include "renderable.h"
35 #include "selectable.h"
37 #include "math/frustum.h"
39 #include "instancelib.h"
40 #include "entitylib.h"
48 RenderableSolidAABB m_aabb_solid;
49 RenderableWireframeAABB m_aabb_wire;
51 NullModel() : m_aabb_local( Vector3( 0, 0, 0 ), Vector3( 8, 8, 8 ) ), m_aabb_solid( m_aabb_local ), m_aabb_wire( m_aabb_local ){
52 m_state = GlobalShaderCache().capture( "" );
55 GlobalShaderCache().release( "" );
58 VolumeIntersectionValue intersectVolume( const VolumeTest& volume, const Matrix4& localToWorld ) const {
59 return volume.TestAABB( m_aabb_local, localToWorld );
62 const AABB& localAABB() const {
66 void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const {
67 renderer.SetState( m_state, Renderer::eFullMaterials );
68 renderer.addRenderable( m_aabb_solid, localToWorld );
70 void renderWireframe( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const {
71 renderer.addRenderable( m_aabb_wire, localToWorld );
74 void testSelect( Selector& selector, SelectionTest& test, const Matrix4& localToWorld ){
75 test.BeginMesh( localToWorld );
77 SelectionIntersection best;
78 aabb_testselect( m_aabb_local, test, best );
80 selector.addIntersection( best );
85 class NullModelInstance : public scene::Instance, public Renderable, public SelectionTestable
89 InstanceTypeCastTable m_casts;
92 InstanceContainedCast<NullModelInstance, Bounded>::install( m_casts );
93 InstanceContainedCast<NullModelInstance, Cullable>::install( m_casts );
94 InstanceStaticCast<NullModelInstance, Renderable>::install( m_casts );
95 InstanceStaticCast<NullModelInstance, SelectionTestable>::install( m_casts );
97 InstanceTypeCastTable& get(){
102 NullModel& m_nullmodel;
105 typedef LazyStatic<TypeCasts> StaticTypeCasts;
107 Bounded& get( NullType<Bounded>){
110 Cullable& get( NullType<Cullable>){
114 NullModelInstance( const scene::Path& path, scene::Instance* parent, NullModel& nullmodel ) :
115 Instance( path, parent, this, StaticTypeCasts::instance().get() ),
116 m_nullmodel( nullmodel ){
119 void renderSolid( Renderer& renderer, const VolumeTest& volume ) const {
120 m_nullmodel.renderSolid( renderer, volume, Instance::localToWorld() );
122 void renderWireframe( Renderer& renderer, const VolumeTest& volume ) const {
123 m_nullmodel.renderWireframe( renderer, volume, Instance::localToWorld() );
126 void testSelect( Selector& selector, SelectionTest& test ){
127 m_nullmodel.testSelect( selector, test, Instance::localToWorld() );
131 class NullModelNode : public scene::Node::Symbiot, public scene::Instantiable
135 NodeTypeCastTable m_casts;
138 NodeStaticCast<NullModelNode, scene::Instantiable>::install( m_casts );
140 NodeTypeCastTable& get(){
147 InstanceSet m_instances;
148 NullModel m_nullmodel;
151 typedef LazyStatic<TypeCasts> StaticTypeCasts;
153 NullModelNode() : m_node( this, this, StaticTypeCasts::instance().get() ){
154 m_node.m_isRoot = true;
164 scene::Instance* create( const scene::Path& path, scene::Instance* parent ){
165 return new NullModelInstance( path, parent, m_nullmodel );
167 void forEachInstance( const scene::Instantiable::Visitor& visitor ){
168 m_instances.forEachInstance( visitor );
170 void insert( scene::Instantiable::Observer* observer, const scene::Path& path, scene::Instance* instance ){
171 m_instances.insert( observer, path, instance );
173 scene::Instance* erase( scene::Instantiable::Observer* observer, const scene::Path& path ){
174 return m_instances.erase( observer, path );
178 NodeSmartReference NewNullModel(){
179 return NodeSmartReference( ( new NullModelNode )->node() );
182 void NullModel_construct(){
184 void NullModel_destroy(){