my own uncrustify run

This commit is contained in:
Rudolf Polzer
2012-03-27 12:03:21 +02:00
parent 203343b01a
commit e4287c28bb
1056 changed files with 194610 additions and 205971 deletions

View File

@@ -1,23 +1,22 @@
/*
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
*/
#include "angle.h"

View File

@@ -1,25 +1,25 @@
/*
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
*/
#if !defined(INCLUDED_ANGLE_H)
#if !defined( INCLUDED_ANGLE_H )
#define INCLUDED_ANGLE_H
#include "ientity.h"
@@ -30,72 +30,62 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
const float ANGLEKEY_IDENTITY = 0;
inline void default_angle(float& angle)
{
angle = ANGLEKEY_IDENTITY;
inline void default_angle( float& angle ){
angle = ANGLEKEY_IDENTITY;
}
inline void normalise_angle(float& angle)
{
angle = static_cast<float>(float_mod(angle, 360.0));
inline void normalise_angle( float& angle ){
angle = static_cast<float>( float_mod( angle, 360.0 ) );
}
inline void read_angle(float& angle, const char* value)
{
if(!string_parse_float(value, angle))
{
angle = 0;
}
else
{
normalise_angle(angle);
}
inline void read_angle( float& angle, const char* value ){
if ( !string_parse_float( value, angle ) ) {
angle = 0;
}
else
{
normalise_angle( angle );
}
}
inline void write_angle(float angle, Entity* entity)
{
if(angle == 0)
{
entity->setKeyValue("angle", "");
}
else
{
char value[64];
sprintf(value, "%f", angle);
entity->setKeyValue("angle", value);
}
inline void write_angle( float angle, Entity* entity ){
if ( angle == 0 ) {
entity->setKeyValue( "angle", "" );
}
else
{
char value[64];
sprintf( value, "%f", angle );
entity->setKeyValue( "angle", value );
}
}
class AngleKey
{
Callback m_angleChanged;
Callback m_angleChanged;
public:
float m_angle;
float m_angle;
AngleKey(const Callback& angleChanged)
: m_angleChanged(angleChanged), m_angle(ANGLEKEY_IDENTITY)
{
}
AngleKey( const Callback& angleChanged )
: m_angleChanged( angleChanged ), m_angle( ANGLEKEY_IDENTITY ){
}
void angleChanged(const char* value)
{
read_angle(m_angle, value);
m_angleChanged();
}
typedef MemberCaller1<AngleKey, const char*, &AngleKey::angleChanged> AngleChangedCaller;
void angleChanged( const char* value ){
read_angle( m_angle, value );
m_angleChanged();
}
typedef MemberCaller1<AngleKey, const char*, &AngleKey::angleChanged> AngleChangedCaller;
void write(Entity* entity) const
{
write_angle(m_angle, entity);
}
void write( Entity* entity ) const {
write_angle( m_angle, entity );
}
};
inline float angle_rotated(float angle, const Quaternion& rotation)
{
return matrix4_get_rotation_euler_xyz_degrees(
matrix4_multiplied_by_matrix4(
matrix4_rotation_for_z_degrees(angle),
matrix4_rotation_for_quaternion_quantised(rotation)
)
).z();
inline float angle_rotated( float angle, const Quaternion& rotation ){
return matrix4_get_rotation_euler_xyz_degrees(
matrix4_multiplied_by_matrix4(
matrix4_rotation_for_z_degrees( angle ),
matrix4_rotation_for_quaternion_quantised( rotation )
)
).z();
}
#endif

View File

@@ -1,23 +1,22 @@
/*
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
*/
#include "angles.h"

View File

@@ -1,25 +1,25 @@
/*
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
*/
#if !defined(INCLUDED_ANGLES_H)
#if !defined( INCLUDED_ANGLES_H )
#define INCLUDED_ANGLES_H
#include "ientity.h"
@@ -30,110 +30,96 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "angle.h"
const Vector3 ANGLESKEY_IDENTITY = Vector3(0, 0, 0);
const Vector3 ANGLESKEY_IDENTITY = Vector3( 0, 0, 0 );
inline void default_angles(Vector3& angles)
{
angles = ANGLESKEY_IDENTITY;
inline void default_angles( Vector3& angles ){
angles = ANGLESKEY_IDENTITY;
}
inline void normalise_angles(Vector3& angles)
{
angles[0] = static_cast<float>(float_mod(angles[0], 360));
angles[1] = static_cast<float>(float_mod(angles[1], 360));
angles[2] = static_cast<float>(float_mod(angles[2], 360));
inline void normalise_angles( Vector3& angles ){
angles[0] = static_cast<float>( float_mod( angles[0], 360 ) );
angles[1] = static_cast<float>( float_mod( angles[1], 360 ) );
angles[2] = static_cast<float>( float_mod( angles[2], 360 ) );
}
inline void read_angle(Vector3& angles, const char* value)
{
if(!string_parse_float(value, angles[2]))
{
default_angles(angles);
}
else
{
angles[0] = 0;
angles[1] = 0;
normalise_angles(angles);
}
inline void read_angle( Vector3& angles, const char* value ){
if ( !string_parse_float( value, angles[2] ) ) {
default_angles( angles );
}
else
{
angles[0] = 0;
angles[1] = 0;
normalise_angles( angles );
}
}
inline void read_angles(Vector3& angles, const char* value)
{
if(!string_parse_vector3(value, angles))
{
default_angles(angles);
}
else
{
angles = Vector3(angles[2], angles[0], angles[1]);
normalise_angles(angles);
}
inline void read_angles( Vector3& angles, const char* value ){
if ( !string_parse_vector3( value, angles ) ) {
default_angles( angles );
}
else
{
angles = Vector3( angles[2], angles[0], angles[1] );
normalise_angles( angles );
}
}
inline void write_angles(const Vector3& angles, Entity* entity)
{
if(angles[0] == 0
&& angles[1] == 0
&& angles[2] == 0)
{
entity->setKeyValue("angle", "");
entity->setKeyValue("angles", "");
}
else
{
char value[64];
inline void write_angles( const Vector3& angles, Entity* entity ){
if ( angles[0] == 0
&& angles[1] == 0
&& angles[2] == 0 ) {
entity->setKeyValue( "angle", "" );
entity->setKeyValue( "angles", "" );
}
else
{
char value[64];
if(angles[0] == 0 && angles[1] == 0)
{
entity->setKeyValue("angles", "");
write_angle(angles[2], entity);
}
else
{
sprintf(value, "%f %f %f", angles[1], angles[2], angles[0]);
entity->setKeyValue("angle", "");
entity->setKeyValue("angles", value);
}
}
if ( angles[0] == 0 && angles[1] == 0 ) {
entity->setKeyValue( "angles", "" );
write_angle( angles[2], entity );
}
else
{
sprintf( value, "%f %f %f", angles[1], angles[2], angles[0] );
entity->setKeyValue( "angle", "" );
entity->setKeyValue( "angles", value );
}
}
}
inline Vector3 angles_rotated(const Vector3& angles, const Quaternion& rotation)
{
return matrix4_get_rotation_euler_xyz_degrees(
matrix4_multiplied_by_matrix4(
matrix4_rotation_for_euler_xyz_degrees(angles),
matrix4_rotation_for_quaternion_quantised(rotation)
)
);
inline Vector3 angles_rotated( const Vector3& angles, const Quaternion& rotation ){
return matrix4_get_rotation_euler_xyz_degrees(
matrix4_multiplied_by_matrix4(
matrix4_rotation_for_euler_xyz_degrees( angles ),
matrix4_rotation_for_quaternion_quantised( rotation )
)
);
}
class AnglesKey
{
Callback m_anglesChanged;
Callback m_anglesChanged;
public:
Vector3 m_angles;
Vector3 m_angles;
AnglesKey(const Callback& anglesChanged)
: m_anglesChanged(anglesChanged), m_angles(ANGLESKEY_IDENTITY)
{
}
AnglesKey( const Callback& anglesChanged )
: m_anglesChanged( anglesChanged ), m_angles( ANGLESKEY_IDENTITY ){
}
void angleChanged(const char* value)
{
read_angle(m_angles, value);
m_anglesChanged();
}
typedef MemberCaller1<AnglesKey, const char*, &AnglesKey::angleChanged> AngleChangedCaller;
void angleChanged( const char* value ){
read_angle( m_angles, value );
m_anglesChanged();
}
typedef MemberCaller1<AnglesKey, const char*, &AnglesKey::angleChanged> AngleChangedCaller;
void anglesChanged(const char* value)
{
read_angles(m_angles, value);
m_anglesChanged();
}
typedef MemberCaller1<AnglesKey, const char*, &AnglesKey::anglesChanged> AnglesChangedCaller;
void anglesChanged( const char* value ){
read_angles( m_angles, value );
m_anglesChanged();
}
typedef MemberCaller1<AnglesKey, const char*, &AnglesKey::anglesChanged> AnglesChangedCaller;
void write(Entity* entity) const
{
write_angles(m_angles, entity);
}
void write( Entity* entity ) const {
write_angles( m_angles, entity );
}
};

View File

@@ -1,23 +1,22 @@
/*
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
*/
#include "colour.h"

View File

@@ -1,25 +1,25 @@
/*
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
*/
#if !defined(INCLUDED_COLOUR_H)
#if !defined( INCLUDED_COLOUR_H )
#define INCLUDED_COLOUR_H
#include "ientity.h"
@@ -30,73 +30,62 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "generic/callback.h"
#include "stringio.h"
inline void default_colour(Vector3& colour)
{
colour = Vector3(1, 1, 1);
inline void default_colour( Vector3& colour ){
colour = Vector3( 1, 1, 1 );
}
inline void read_colour(Vector3& colour, const char* value)
{
if(!string_parse_vector3(value, colour))
{
default_colour(colour);
}
inline void read_colour( Vector3& colour, const char* value ){
if ( !string_parse_vector3( value, colour ) ) {
default_colour( colour );
}
}
inline void write_colour(const Vector3& colour, Entity* entity)
{
char value[64];
inline void write_colour( const Vector3& colour, Entity* entity ){
char value[64];
sprintf(value, "%f %f %f", colour[0], colour[1], colour[2]);
entity->setKeyValue("_color", value);
sprintf( value, "%f %f %f", colour[0], colour[1], colour[2] );
entity->setKeyValue( "_color", value );
}
class Colour
{
Callback m_colourChanged;
Shader* m_state;
Callback m_colourChanged;
Shader* m_state;
void capture_state()
{
m_state = colour_capture_state_fill(m_colour);
}
void release_state()
{
colour_release_state_fill(m_colour);
}
void capture_state(){
m_state = colour_capture_state_fill( m_colour );
}
void release_state(){
colour_release_state_fill( m_colour );
}
public:
Vector3 m_colour;
Vector3 m_colour;
Colour(const Callback& colourChanged)
: m_colourChanged(colourChanged)
{
default_colour(m_colour);
capture_state();
}
~Colour()
{
release_state();
}
Colour( const Callback& colourChanged )
: m_colourChanged( colourChanged ){
default_colour( m_colour );
capture_state();
}
~Colour(){
release_state();
}
void colourChanged(const char* value)
{
release_state();
read_colour(m_colour, value);
capture_state();
void colourChanged( const char* value ){
release_state();
read_colour( m_colour, value );
capture_state();
m_colourChanged();
}
typedef MemberCaller1<Colour, const char*, &Colour::colourChanged> ColourChangedCaller;
m_colourChanged();
}
typedef MemberCaller1<Colour, const char*, &Colour::colourChanged> ColourChangedCaller;
void write(Entity* entity) const
{
write_colour(m_colour, entity);
}
void write( Entity* entity ) const {
write_colour( m_colour, entity );
}
Shader* state() const
{
return m_state;
}
Shader* state() const {
return m_state;
}
};
#endif

View File

@@ -1,23 +1,22 @@
/*
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
*/
#include "curve.h"

View File

@@ -1,25 +1,25 @@
/*
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
*/
#if !defined(INCLUDED_CURVE_H)
#if !defined( INCLUDED_CURVE_H )
#define INCLUDED_CURVE_H
#include "ientity.h"
@@ -38,297 +38,258 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
class RenderableCurve : public OpenGLRenderable
{
public:
std::vector<PointVertex> m_vertices;
void render(RenderStateFlags state) const
{
pointvertex_gl_array(&m_vertices.front());
glDrawArrays(GL_LINE_STRIP, 0, GLsizei(m_vertices.size()));
}
std::vector<PointVertex> m_vertices;
void render( RenderStateFlags state ) const {
pointvertex_gl_array( &m_vertices.front() );
glDrawArrays( GL_LINE_STRIP, 0, GLsizei( m_vertices.size() ) );
}
};
inline void plotBasisFunction(std::size_t numSegments, int point, int degree)
{
Knots knots;
KnotVector_openUniform(knots, 4, degree);
inline void plotBasisFunction( std::size_t numSegments, int point, int degree ){
Knots knots;
KnotVector_openUniform( knots, 4, degree );
globalOutputStream() << "plotBasisFunction point " << point << " of 4, knot vector:";
for(Knots::iterator i = knots.begin(); i != knots.end(); ++i)
{
globalOutputStream() << " " << *i;
}
globalOutputStream() << "\n";
globalOutputStream() << "t=0 basis=" << BSpline_basis(knots, point, degree, 0.0) << "\n";
for(std::size_t i = 1; i < numSegments; ++i)
{
double t = (1.0 / double(numSegments)) * double(i);
globalOutputStream() << "t=" << t << " basis=" << BSpline_basis(knots, point, degree, t) << "\n";
}
globalOutputStream() << "t=1 basis=" << BSpline_basis(knots, point, degree, 1.0) << "\n";
globalOutputStream() << "plotBasisFunction point " << point << " of 4, knot vector:";
for ( Knots::iterator i = knots.begin(); i != knots.end(); ++i )
{
globalOutputStream() << " " << *i;
}
globalOutputStream() << "\n";
globalOutputStream() << "t=0 basis=" << BSpline_basis( knots, point, degree, 0.0 ) << "\n";
for ( std::size_t i = 1; i < numSegments; ++i )
{
double t = ( 1.0 / double(numSegments) ) * double(i);
globalOutputStream() << "t=" << t << " basis=" << BSpline_basis( knots, point, degree, t ) << "\n";
}
globalOutputStream() << "t=1 basis=" << BSpline_basis( knots, point, degree, 1.0 ) << "\n";
}
inline bool ControlPoints_parse(ControlPoints& controlPoints, const char* value)
{
StringTokeniser tokeniser(value, " ");
inline bool ControlPoints_parse( ControlPoints& controlPoints, const char* value ){
StringTokeniser tokeniser( value, " " );
std::size_t size;
if(!string_parse_size(tokeniser.getToken(), size))
{
return false;
}
std::size_t size;
if ( !string_parse_size( tokeniser.getToken(), size ) ) {
return false;
}
if(size < 3)
{
return false;
}
controlPoints.resize(size);
if ( size < 3 ) {
return false;
}
controlPoints.resize( size );
if(!string_equal(tokeniser.getToken(), "("))
{
return false;
}
for(ControlPoints::iterator i = controlPoints.begin(); i != controlPoints.end(); ++i)
{
if(!string_parse_float(tokeniser.getToken(), (*i).x())
|| !string_parse_float(tokeniser.getToken(), (*i).y())
|| !string_parse_float(tokeniser.getToken(), (*i).z()))
{
return false;
}
}
if(!string_equal(tokeniser.getToken(), ")"))
{
return false;
}
return true;
if ( !string_equal( tokeniser.getToken(), "(" ) ) {
return false;
}
for ( ControlPoints::iterator i = controlPoints.begin(); i != controlPoints.end(); ++i )
{
if ( !string_parse_float( tokeniser.getToken(), ( *i ).x() )
|| !string_parse_float( tokeniser.getToken(), ( *i ).y() )
|| !string_parse_float( tokeniser.getToken(), ( *i ).z() ) ) {
return false;
}
}
if ( !string_equal( tokeniser.getToken(), ")" ) ) {
return false;
}
return true;
}
inline void ControlPoints_write(const ControlPoints& controlPoints, StringOutputStream& value)
{
value << Unsigned(controlPoints.size()) << " (";
for(ControlPoints::const_iterator i = controlPoints.begin(); i != controlPoints.end(); ++i)
{
value << " " << (*i).x() << " " << (*i).y() << " " << (*i).z() << " ";
}
value << ")";
inline void ControlPoints_write( const ControlPoints& controlPoints, StringOutputStream& value ){
value << Unsigned( controlPoints.size() ) << " (";
for ( ControlPoints::const_iterator i = controlPoints.begin(); i != controlPoints.end(); ++i )
{
value << " " << ( *i ).x() << " " << ( *i ).y() << " " << ( *i ).z() << " ";
}
value << ")";
}
inline void ControlPoint_testSelect(const Vector3& point, ObservedSelectable& selectable, Selector& selector, SelectionTest& test)
{
SelectionIntersection best;
test.TestPoint(point, best);
if(best.valid())
{
Selector_add(selector, selectable, best);
}
inline void ControlPoint_testSelect( const Vector3& point, ObservedSelectable& selectable, Selector& selector, SelectionTest& test ){
SelectionIntersection best;
test.TestPoint( point, best );
if ( best.valid() ) {
Selector_add( selector, selectable, best );
}
}
class ControlPointTransform
{
const Matrix4& m_matrix;
const Matrix4& m_matrix;
public:
ControlPointTransform(const Matrix4& matrix) : m_matrix(matrix)
{
}
void operator()(Vector3& point) const
{
matrix4_transform_point(m_matrix, point);
}
ControlPointTransform( const Matrix4& matrix ) : m_matrix( matrix ){
}
void operator()( Vector3& point ) const {
matrix4_transform_point( m_matrix, point );
}
};
class ControlPointSnap
{
float m_snap;
float m_snap;
public:
ControlPointSnap(float snap) : m_snap(snap)
{
}
void operator()(Vector3& point) const
{
vector3_snap(point, m_snap);
}
ControlPointSnap( float snap ) : m_snap( snap ){
}
void operator()( Vector3& point ) const {
vector3_snap( point, m_snap );
}
};
class ControlPointAdd
{
RenderablePointVector& m_points;
RenderablePointVector& m_points;
public:
ControlPointAdd(RenderablePointVector& points) : m_points(points)
{
}
void operator()(const Vector3& point) const
{
m_points.push_back(PointVertex(vertex3f_for_vector3(point), colour_vertex));
}
ControlPointAdd( RenderablePointVector& points ) : m_points( points ){
}
void operator()( const Vector3& point ) const {
m_points.push_back( PointVertex( vertex3f_for_vector3( point ), colour_vertex ) );
}
};
class ControlPointAddSelected
{
RenderablePointVector& m_points;
RenderablePointVector& m_points;
public:
ControlPointAddSelected(RenderablePointVector& points) : m_points(points)
{
}
void operator()(const Vector3& point) const
{
m_points.push_back(PointVertex(vertex3f_for_vector3(point), colour_selected));
}
ControlPointAddSelected( RenderablePointVector& points ) : m_points( points ){
}
void operator()( const Vector3& point ) const {
m_points.push_back( PointVertex( vertex3f_for_vector3( point ), colour_selected ) );
}
};
class CurveEditType
{
public:
Shader* m_controlsShader;
Shader* m_selectedShader;
Shader* m_controlsShader;
Shader* m_selectedShader;
};
inline void ControlPoints_write(ControlPoints& controlPoints, const char* key, Entity& entity)
{
StringOutputStream value(256);
if(!controlPoints.empty())
{
ControlPoints_write(controlPoints, value);
}
entity.setKeyValue(key, value.c_str());
inline void ControlPoints_write( ControlPoints& controlPoints, const char* key, Entity& entity ){
StringOutputStream value( 256 );
if ( !controlPoints.empty() ) {
ControlPoints_write( controlPoints, value );
}
entity.setKeyValue( key, value.c_str() );
}
class CurveEdit
{
SelectionChangeCallback m_selectionChanged;
ControlPoints& m_controlPoints;
typedef Array<ObservedSelectable> Selectables;
Selectables m_selectables;
SelectionChangeCallback m_selectionChanged;
ControlPoints& m_controlPoints;
typedef Array<ObservedSelectable> Selectables;
Selectables m_selectables;
RenderablePointVector m_controlsRender;
mutable RenderablePointVector m_selectedRender;
RenderablePointVector m_controlsRender;
mutable RenderablePointVector m_selectedRender;
public:
typedef Static<CurveEditType> Type;
typedef Static<CurveEditType> Type;
CurveEdit(ControlPoints& controlPoints, const SelectionChangeCallback& selectionChanged) :
m_selectionChanged(selectionChanged),
m_controlPoints(controlPoints),
m_controlsRender(GL_POINTS),
m_selectedRender(GL_POINTS)
{
}
CurveEdit( ControlPoints& controlPoints, const SelectionChangeCallback& selectionChanged ) :
m_selectionChanged( selectionChanged ),
m_controlPoints( controlPoints ),
m_controlsRender( GL_POINTS ),
m_selectedRender( GL_POINTS ){
}
template<typename Functor>
const Functor& forEachSelected(const Functor& functor)
{
ASSERT_MESSAGE(m_controlPoints.size() == m_selectables.size(), "curve instance mismatch");
ControlPoints::iterator p = m_controlPoints.begin();
for(Selectables::iterator i = m_selectables.begin(); i != m_selectables.end(); ++i, ++p)
{
if((*i).isSelected())
{
functor(*p);
}
}
return functor;
}
template<typename Functor>
const Functor& forEachSelected(const Functor& functor) const
{
ASSERT_MESSAGE(m_controlPoints.size() == m_selectables.size(), "curve instance mismatch");
ControlPoints::const_iterator p = m_controlPoints.begin();
for(Selectables::const_iterator i = m_selectables.begin(); i != m_selectables.end(); ++i, ++p)
{
if((*i).isSelected())
{
functor(*p);
}
}
return functor;
}
template<typename Functor>
const Functor& forEach(const Functor& functor) const
{
for(ControlPoints::const_iterator i = m_controlPoints.begin(); i != m_controlPoints.end(); ++i)
{
functor(*i);
}
return functor;
}
template<typename Functor>
const Functor& forEachSelected( const Functor& functor ){
ASSERT_MESSAGE( m_controlPoints.size() == m_selectables.size(), "curve instance mismatch" );
ControlPoints::iterator p = m_controlPoints.begin();
for ( Selectables::iterator i = m_selectables.begin(); i != m_selectables.end(); ++i, ++p )
{
if ( ( *i ).isSelected() ) {
functor( *p );
}
}
return functor;
}
template<typename Functor>
const Functor& forEachSelected( const Functor& functor ) const {
ASSERT_MESSAGE( m_controlPoints.size() == m_selectables.size(), "curve instance mismatch" );
ControlPoints::const_iterator p = m_controlPoints.begin();
for ( Selectables::const_iterator i = m_selectables.begin(); i != m_selectables.end(); ++i, ++p )
{
if ( ( *i ).isSelected() ) {
functor( *p );
}
}
return functor;
}
template<typename Functor>
const Functor& forEach( const Functor& functor ) const {
for ( ControlPoints::const_iterator i = m_controlPoints.begin(); i != m_controlPoints.end(); ++i )
{
functor( *i );
}
return functor;
}
void testSelect(Selector& selector, SelectionTest& test)
{
ASSERT_MESSAGE(m_controlPoints.size() == m_selectables.size(), "curve instance mismatch");
ControlPoints::const_iterator p = m_controlPoints.begin();
for(Selectables::iterator i = m_selectables.begin(); i != m_selectables.end(); ++i, ++p)
{
ControlPoint_testSelect(*p, *i, selector, test);
}
}
void testSelect( Selector& selector, SelectionTest& test ){
ASSERT_MESSAGE( m_controlPoints.size() == m_selectables.size(), "curve instance mismatch" );
ControlPoints::const_iterator p = m_controlPoints.begin();
for ( Selectables::iterator i = m_selectables.begin(); i != m_selectables.end(); ++i, ++p )
{
ControlPoint_testSelect( *p, *i, selector, test );
}
}
bool isSelected() const
{
for(Selectables::const_iterator i = m_selectables.begin(); i != m_selectables.end(); ++i)
{
if((*i).isSelected())
{
return true;
}
}
return false;
}
void setSelected(bool selected)
{
for(Selectables::iterator i = m_selectables.begin(); i != m_selectables.end(); ++i)
{
(*i).setSelected(selected);
}
}
bool isSelected() const {
for ( Selectables::const_iterator i = m_selectables.begin(); i != m_selectables.end(); ++i )
{
if ( ( *i ).isSelected() ) {
return true;
}
}
return false;
}
void setSelected( bool selected ){
for ( Selectables::iterator i = m_selectables.begin(); i != m_selectables.end(); ++i )
{
( *i ).setSelected( selected );
}
}
void write(const char* key, Entity& entity)
{
ControlPoints_write(m_controlPoints, key, entity);
}
void write( const char* key, Entity& entity ){
ControlPoints_write( m_controlPoints, key, entity );
}
void transform(const Matrix4& matrix)
{
forEachSelected(ControlPointTransform(matrix));
}
void snapto(float snap)
{
forEachSelected(ControlPointSnap(snap));
}
void transform( const Matrix4& matrix ){
forEachSelected( ControlPointTransform( matrix ) );
}
void snapto( float snap ){
forEachSelected( ControlPointSnap( snap ) );
}
void updateSelected() const
{
m_selectedRender.clear();
forEachSelected(ControlPointAddSelected(m_selectedRender));
}
void renderComponents(Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld) const
{
renderer.SetState(Type::instance().m_controlsShader, Renderer::eWireframeOnly);
renderer.SetState(Type::instance().m_controlsShader, Renderer::eFullMaterials);
renderer.addRenderable(m_controlsRender, localToWorld);
}
void updateSelected() const {
m_selectedRender.clear();
forEachSelected( ControlPointAddSelected( m_selectedRender ) );
}
void renderComponentsSelected(Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld) const
{
updateSelected();
if(!m_selectedRender.empty())
{
renderer.Highlight(Renderer::ePrimitive, false);
renderer.SetState(Type::instance().m_selectedShader, Renderer::eWireframeOnly);
renderer.SetState(Type::instance().m_selectedShader, Renderer::eFullMaterials);
renderer.addRenderable(m_selectedRender, localToWorld);
}
}
void renderComponents( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const {
renderer.SetState( Type::instance().m_controlsShader, Renderer::eWireframeOnly );
renderer.SetState( Type::instance().m_controlsShader, Renderer::eFullMaterials );
renderer.addRenderable( m_controlsRender, localToWorld );
}
void curveChanged()
{
m_selectables.resize(m_controlPoints.size(), m_selectionChanged);
void renderComponentsSelected( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const {
updateSelected();
if ( !m_selectedRender.empty() ) {
renderer.Highlight( Renderer::ePrimitive, false );
renderer.SetState( Type::instance().m_selectedShader, Renderer::eWireframeOnly );
renderer.SetState( Type::instance().m_selectedShader, Renderer::eFullMaterials );
renderer.addRenderable( m_selectedRender, localToWorld );
}
}
m_controlsRender.clear();
m_controlsRender.reserve(m_controlPoints.size());
forEach(ControlPointAdd(m_controlsRender));
void curveChanged(){
m_selectables.resize( m_controlPoints.size(), m_selectionChanged );
m_selectedRender.reserve(m_controlPoints.size());
}
typedef MemberCaller<CurveEdit, &CurveEdit::curveChanged> CurveChangedCaller;
m_controlsRender.clear();
m_controlsRender.reserve( m_controlPoints.size() );
forEach( ControlPointAdd( m_controlsRender ) );
m_selectedRender.reserve( m_controlPoints.size() );
}
typedef MemberCaller<CurveEdit, &CurveEdit::curveChanged> CurveChangedCaller;
};
@@ -337,177 +298,156 @@ const int NURBS_degree = 3;
class NURBSCurve
{
Signal0 m_curveChanged;
Callback m_boundsChanged;
Signal0 m_curveChanged;
Callback m_boundsChanged;
public:
ControlPoints m_controlPoints;
ControlPoints m_controlPointsTransformed;
NURBSWeights m_weights;
Knots m_knots;
RenderableCurve m_renderCurve;
AABB m_bounds;
ControlPoints m_controlPoints;
ControlPoints m_controlPointsTransformed;
NURBSWeights m_weights;
Knots m_knots;
RenderableCurve m_renderCurve;
AABB m_bounds;
NURBSCurve(const Callback& boundsChanged) : m_boundsChanged(boundsChanged)
{
}
NURBSCurve( const Callback& boundsChanged ) : m_boundsChanged( boundsChanged ){
}
SignalHandlerId connect(const SignalHandler& curveChanged)
{
curveChanged();
return m_curveChanged.connectLast(curveChanged);
}
void disconnect(SignalHandlerId id)
{
m_curveChanged.disconnect(id);
}
void notify()
{
m_curveChanged();
}
SignalHandlerId connect( const SignalHandler& curveChanged ){
curveChanged();
return m_curveChanged.connectLast( curveChanged );
}
void disconnect( SignalHandlerId id ){
m_curveChanged.disconnect( id );
}
void notify(){
m_curveChanged();
}
void tesselate()
{
if(!m_controlPointsTransformed.empty())
{
const std::size_t numSegments = (m_controlPointsTransformed.size() - 1) * 16;
m_renderCurve.m_vertices.resize(numSegments + 1);
m_renderCurve.m_vertices[0].vertex = vertex3f_for_vector3(m_controlPointsTransformed[0]);
for(std::size_t i = 1; i < numSegments; ++i)
{
m_renderCurve.m_vertices[i].vertex = vertex3f_for_vector3(NURBS_evaluate(m_controlPointsTransformed, m_weights, m_knots, NURBS_degree, (1.0 / double(numSegments)) * double(i)));
}
m_renderCurve.m_vertices[numSegments].vertex = vertex3f_for_vector3(m_controlPointsTransformed[m_controlPointsTransformed.size() - 1]);
}
else
{
m_renderCurve.m_vertices.clear();
}
}
void tesselate(){
if ( !m_controlPointsTransformed.empty() ) {
const std::size_t numSegments = ( m_controlPointsTransformed.size() - 1 ) * 16;
m_renderCurve.m_vertices.resize( numSegments + 1 );
m_renderCurve.m_vertices[0].vertex = vertex3f_for_vector3( m_controlPointsTransformed[0] );
for ( std::size_t i = 1; i < numSegments; ++i )
{
m_renderCurve.m_vertices[i].vertex = vertex3f_for_vector3( NURBS_evaluate( m_controlPointsTransformed, m_weights, m_knots, NURBS_degree, ( 1.0 / double(numSegments) ) * double(i) ) );
}
m_renderCurve.m_vertices[numSegments].vertex = vertex3f_for_vector3( m_controlPointsTransformed[m_controlPointsTransformed.size() - 1] );
}
else
{
m_renderCurve.m_vertices.clear();
}
}
void curveChanged()
{
tesselate();
void curveChanged(){
tesselate();
m_bounds = AABB();
for(ControlPoints::iterator i = m_controlPointsTransformed.begin(); i != m_controlPointsTransformed.end(); ++i)
{
aabb_extend_by_point_safe(m_bounds, (*i));
}
m_bounds = AABB();
for ( ControlPoints::iterator i = m_controlPointsTransformed.begin(); i != m_controlPointsTransformed.end(); ++i )
{
aabb_extend_by_point_safe( m_bounds, ( *i ) );
}
m_boundsChanged();
notify();
}
m_boundsChanged();
notify();
}
bool parseCurve(const char* value)
{
if(!ControlPoints_parse(m_controlPoints, value))
{
return false;
}
bool parseCurve( const char* value ){
if ( !ControlPoints_parse( m_controlPoints, value ) ) {
return false;
}
m_weights.resize(m_controlPoints.size());
for(NURBSWeights::iterator i = m_weights.begin(); i != m_weights.end(); ++i)
{
(*i) = 1;
}
m_weights.resize( m_controlPoints.size() );
for ( NURBSWeights::iterator i = m_weights.begin(); i != m_weights.end(); ++i )
{
( *i ) = 1;
}
KnotVector_openUniform(m_knots, m_controlPoints.size(), NURBS_degree);
KnotVector_openUniform( m_knots, m_controlPoints.size(), NURBS_degree );
//plotBasisFunction(8, 0, NURBS_degree);
//plotBasisFunction(8, 0, NURBS_degree);
return true;
}
return true;
}
void curveChanged(const char* value)
{
if(string_empty(value) || !parseCurve(value))
{
m_controlPoints.resize(0);
m_knots.resize(0);
m_weights.resize(0);
}
m_controlPointsTransformed = m_controlPoints;
curveChanged();
}
typedef MemberCaller1<NURBSCurve, const char*, &NURBSCurve::curveChanged> CurveChangedCaller;
void curveChanged( const char* value ){
if ( string_empty( value ) || !parseCurve( value ) ) {
m_controlPoints.resize( 0 );
m_knots.resize( 0 );
m_weights.resize( 0 );
}
m_controlPointsTransformed = m_controlPoints;
curveChanged();
}
typedef MemberCaller1<NURBSCurve, const char*, &NURBSCurve::curveChanged> CurveChangedCaller;
};
class CatmullRomSpline
{
Signal0 m_curveChanged;
Callback m_boundsChanged;
Signal0 m_curveChanged;
Callback m_boundsChanged;
public:
ControlPoints m_controlPoints;
ControlPoints m_controlPointsTransformed;
RenderableCurve m_renderCurve;
AABB m_bounds;
ControlPoints m_controlPoints;
ControlPoints m_controlPointsTransformed;
RenderableCurve m_renderCurve;
AABB m_bounds;
CatmullRomSpline(const Callback& boundsChanged) : m_boundsChanged(boundsChanged)
{
}
CatmullRomSpline( const Callback& boundsChanged ) : m_boundsChanged( boundsChanged ){
}
SignalHandlerId connect(const SignalHandler& curveChanged)
{
curveChanged();
return m_curveChanged.connectLast(curveChanged);
}
void disconnect(SignalHandlerId id)
{
m_curveChanged.disconnect(id);
}
void notify()
{
m_curveChanged();
}
SignalHandlerId connect( const SignalHandler& curveChanged ){
curveChanged();
return m_curveChanged.connectLast( curveChanged );
}
void disconnect( SignalHandlerId id ){
m_curveChanged.disconnect( id );
}
void notify(){
m_curveChanged();
}
void tesselate()
{
if(!m_controlPointsTransformed.empty())
{
const std::size_t numSegments = (m_controlPointsTransformed.size() - 1) * 16;
m_renderCurve.m_vertices.resize(numSegments + 1);
m_renderCurve.m_vertices[0].vertex = vertex3f_for_vector3(m_controlPointsTransformed[0]);
for(std::size_t i = 1; i < numSegments; ++i)
{
m_renderCurve.m_vertices[i].vertex = vertex3f_for_vector3(CatmullRom_evaluate(m_controlPointsTransformed, (1.0 / double(numSegments)) * double(i)));
}
m_renderCurve.m_vertices[numSegments].vertex = vertex3f_for_vector3(m_controlPointsTransformed[m_controlPointsTransformed.size() - 1]);
}
else
{
m_renderCurve.m_vertices.clear();
}
}
void tesselate(){
if ( !m_controlPointsTransformed.empty() ) {
const std::size_t numSegments = ( m_controlPointsTransformed.size() - 1 ) * 16;
m_renderCurve.m_vertices.resize( numSegments + 1 );
m_renderCurve.m_vertices[0].vertex = vertex3f_for_vector3( m_controlPointsTransformed[0] );
for ( std::size_t i = 1; i < numSegments; ++i )
{
m_renderCurve.m_vertices[i].vertex = vertex3f_for_vector3( CatmullRom_evaluate( m_controlPointsTransformed, ( 1.0 / double(numSegments) ) * double(i) ) );
}
m_renderCurve.m_vertices[numSegments].vertex = vertex3f_for_vector3( m_controlPointsTransformed[m_controlPointsTransformed.size() - 1] );
}
else
{
m_renderCurve.m_vertices.clear();
}
}
bool parseCurve(const char* value)
{
return ControlPoints_parse(m_controlPoints, value);
}
bool parseCurve( const char* value ){
return ControlPoints_parse( m_controlPoints, value );
}
void curveChanged()
{
tesselate();
void curveChanged(){
tesselate();
m_bounds = AABB();
for(ControlPoints::iterator i = m_controlPointsTransformed.begin(); i != m_controlPointsTransformed.end(); ++i)
{
aabb_extend_by_point_safe(m_bounds, (*i));
}
m_bounds = AABB();
for ( ControlPoints::iterator i = m_controlPointsTransformed.begin(); i != m_controlPointsTransformed.end(); ++i )
{
aabb_extend_by_point_safe( m_bounds, ( *i ) );
}
m_boundsChanged();
notify();
}
m_boundsChanged();
notify();
}
void curveChanged(const char* value)
{
if(string_empty(value) || !parseCurve(value))
{
m_controlPoints.resize(0);
}
m_controlPointsTransformed = m_controlPoints;
curveChanged();
}
typedef MemberCaller1<CatmullRomSpline, const char*, &CatmullRomSpline::curveChanged> CurveChangedCaller;
void curveChanged( const char* value ){
if ( string_empty( value ) || !parseCurve( value ) ) {
m_controlPoints.resize( 0 );
}
m_controlPointsTransformed = m_controlPoints;
curveChanged();
}
typedef MemberCaller1<CatmullRomSpline, const char*, &CatmullRomSpline::curveChanged> CurveChangedCaller;
};
const char* const curve_Nurbs = "curve_Nurbs";

File diff suppressed because it is too large Load Diff

View File

@@ -1,35 +1,35 @@
/*
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
*/
#if !defined(INCLUDED_STATIC_H)
#if !defined( INCLUDED_STATIC_H )
#define INCLUDED_STATIC_H
namespace scene
{
class Node;
class Node;
}
class EntityClass;
void Doom3Group_construct();
void Doom3Group_destroy();
scene::Node& New_Doom3Group(EntityClass* eclass);
scene::Node& New_Doom3Group( EntityClass* eclass );
#endif

View File

@@ -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 entity which has a fixed size specified in its entity-definition and displays a model (e.g. ammo_bfg).
@@ -55,478 +55,406 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "entity.h"
class EclassModel :
public Snappable
public Snappable
{
MatrixTransform m_transform;
EntityKeyValues m_entity;
KeyObserverMap m_keyObservers;
MatrixTransform m_transform;
EntityKeyValues m_entity;
KeyObserverMap m_keyObservers;
OriginKey m_originKey;
Vector3 m_origin;
AngleKey m_angleKey;
float m_angle;
RotationKey m_rotationKey;
Float9 m_rotation;
SingletonModel m_model;
OriginKey m_originKey;
Vector3 m_origin;
AngleKey m_angleKey;
float m_angle;
RotationKey m_rotationKey;
Float9 m_rotation;
SingletonModel m_model;
ClassnameFilter m_filter;
NamedEntity m_named;
NameKeys m_nameKeys;
RenderablePivot m_renderOrigin;
RenderableNamedEntity m_renderName;
ModelSkinKey m_skin;
ClassnameFilter m_filter;
NamedEntity m_named;
NameKeys m_nameKeys;
RenderablePivot m_renderOrigin;
RenderableNamedEntity m_renderName;
ModelSkinKey m_skin;
Callback m_transformChanged;
Callback m_evaluateTransform;
Callback m_transformChanged;
Callback m_evaluateTransform;
void construct()
{
default_rotation(m_rotation);
void construct(){
default_rotation( m_rotation );
m_keyObservers.insert("classname", ClassnameFilter::ClassnameChangedCaller(m_filter));
m_keyObservers.insert(Static<KeyIsName>::instance().m_nameKey, NamedEntity::IdentifierChangedCaller(m_named));
if(g_gameType == eGameTypeDoom3)
{
m_keyObservers.insert("angle", RotationKey::AngleChangedCaller(m_rotationKey));
m_keyObservers.insert("rotation", RotationKey::RotationChangedCaller(m_rotationKey));
}
else
{
m_keyObservers.insert("angle", AngleKey::AngleChangedCaller(m_angleKey));
}
m_keyObservers.insert("origin", OriginKey::OriginChangedCaller(m_originKey));
}
m_keyObservers.insert( "classname", ClassnameFilter::ClassnameChangedCaller( m_filter ) );
m_keyObservers.insert( Static<KeyIsName>::instance().m_nameKey, NamedEntity::IdentifierChangedCaller( m_named ) );
if ( g_gameType == eGameTypeDoom3 ) {
m_keyObservers.insert( "angle", RotationKey::AngleChangedCaller( m_rotationKey ) );
m_keyObservers.insert( "rotation", RotationKey::RotationChangedCaller( m_rotationKey ) );
}
else
{
m_keyObservers.insert( "angle", AngleKey::AngleChangedCaller( m_angleKey ) );
}
m_keyObservers.insert( "origin", OriginKey::OriginChangedCaller( m_originKey ) );
}
// vc 2k5 compiler fix
#if _MSC_VER >= 1400
public:
public:
#endif
void updateTransform()
{
m_transform.localToParent() = g_matrix4_identity;
matrix4_translate_by_vec3(m_transform.localToParent(), m_origin);
void updateTransform(){
m_transform.localToParent() = g_matrix4_identity;
matrix4_translate_by_vec3( m_transform.localToParent(), m_origin );
if(g_gameType == eGameTypeDoom3)
{
matrix4_multiply_by_matrix4(m_transform.localToParent(), rotation_toMatrix(m_rotation));
}
else
{
matrix4_multiply_by_matrix4(m_transform.localToParent(), matrix4_rotation_for_z_degrees(m_angle));
}
if ( g_gameType == eGameTypeDoom3 ) {
matrix4_multiply_by_matrix4( m_transform.localToParent(), rotation_toMatrix( m_rotation ) );
}
else
{
matrix4_multiply_by_matrix4( m_transform.localToParent(), matrix4_rotation_for_z_degrees( m_angle ) );
}
m_transformChanged();
}
typedef MemberCaller<EclassModel, &EclassModel::updateTransform> UpdateTransformCaller;
m_transformChanged();
}
typedef MemberCaller<EclassModel, &EclassModel::updateTransform> UpdateTransformCaller;
void originChanged()
{
m_origin = m_originKey.m_origin;
updateTransform();
}
typedef MemberCaller<EclassModel, &EclassModel::originChanged> OriginChangedCaller;
void angleChanged()
{
m_angle = m_angleKey.m_angle;
updateTransform();
}
typedef MemberCaller<EclassModel, &EclassModel::angleChanged> AngleChangedCaller;
void rotationChanged()
{
rotation_assign(m_rotation, m_rotationKey.m_rotation);
updateTransform();
}
typedef MemberCaller<EclassModel, &EclassModel::rotationChanged> RotationChangedCaller;
void originChanged(){
m_origin = m_originKey.m_origin;
updateTransform();
}
typedef MemberCaller<EclassModel, &EclassModel::originChanged> OriginChangedCaller;
void angleChanged(){
m_angle = m_angleKey.m_angle;
updateTransform();
}
typedef MemberCaller<EclassModel, &EclassModel::angleChanged> AngleChangedCaller;
void rotationChanged(){
rotation_assign( m_rotation, m_rotationKey.m_rotation );
updateTransform();
}
typedef MemberCaller<EclassModel, &EclassModel::rotationChanged> RotationChangedCaller;
void skinChanged()
{
scene::Node* node = m_model.getNode();
if(node != 0)
{
Node_modelSkinChanged(*node);
}
}
typedef MemberCaller<EclassModel, &EclassModel::skinChanged> SkinChangedCaller;
void skinChanged(){
scene::Node* node = m_model.getNode();
if ( node != 0 ) {
Node_modelSkinChanged( *node );
}
}
typedef MemberCaller<EclassModel, &EclassModel::skinChanged> SkinChangedCaller;
public:
EclassModel(EntityClass* eclass, scene::Node& node, const Callback& transformChanged, const Callback& evaluateTransform) :
m_entity(eclass),
m_originKey(OriginChangedCaller(*this)),
m_origin(ORIGINKEY_IDENTITY),
m_angleKey(AngleChangedCaller(*this)),
m_angle(ANGLEKEY_IDENTITY),
m_rotationKey(RotationChangedCaller(*this)),
m_filter(m_entity, node),
m_named(m_entity),
m_nameKeys(m_entity),
m_renderName(m_named, g_vector3_identity),
m_skin(SkinChangedCaller(*this)),
m_transformChanged(transformChanged),
m_evaluateTransform(evaluateTransform)
{
construct();
}
EclassModel(const EclassModel& other, scene::Node& node, const Callback& transformChanged, const Callback& evaluateTransform) :
m_entity(other.m_entity),
m_originKey(OriginChangedCaller(*this)),
m_origin(ORIGINKEY_IDENTITY),
m_angleKey(AngleChangedCaller(*this)),
m_angle(ANGLEKEY_IDENTITY),
m_rotationKey(RotationChangedCaller(*this)),
m_filter(m_entity, node),
m_named(m_entity),
m_nameKeys(m_entity),
m_renderName(m_named, g_vector3_identity),
m_skin(SkinChangedCaller(*this)),
m_transformChanged(transformChanged),
m_evaluateTransform(evaluateTransform)
{
construct();
}
EclassModel( EntityClass* eclass, scene::Node& node, const Callback& transformChanged, const Callback& evaluateTransform ) :
m_entity( eclass ),
m_originKey( OriginChangedCaller( *this ) ),
m_origin( ORIGINKEY_IDENTITY ),
m_angleKey( AngleChangedCaller( *this ) ),
m_angle( ANGLEKEY_IDENTITY ),
m_rotationKey( RotationChangedCaller( *this ) ),
m_filter( m_entity, node ),
m_named( m_entity ),
m_nameKeys( m_entity ),
m_renderName( m_named, g_vector3_identity ),
m_skin( SkinChangedCaller( *this ) ),
m_transformChanged( transformChanged ),
m_evaluateTransform( evaluateTransform ){
construct();
}
EclassModel( const EclassModel& other, scene::Node& node, const Callback& transformChanged, const Callback& evaluateTransform ) :
m_entity( other.m_entity ),
m_originKey( OriginChangedCaller( *this ) ),
m_origin( ORIGINKEY_IDENTITY ),
m_angleKey( AngleChangedCaller( *this ) ),
m_angle( ANGLEKEY_IDENTITY ),
m_rotationKey( RotationChangedCaller( *this ) ),
m_filter( m_entity, node ),
m_named( m_entity ),
m_nameKeys( m_entity ),
m_renderName( m_named, g_vector3_identity ),
m_skin( SkinChangedCaller( *this ) ),
m_transformChanged( transformChanged ),
m_evaluateTransform( evaluateTransform ){
construct();
}
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_entity.attach(m_keyObservers);
m_model.modelChanged(m_entity.getEntityClass().modelpath());
m_skin.skinChanged(m_entity.getEntityClass().skin());
}
}
void instanceDetach(const scene::Path& path)
{
if(--m_instanceCounter.m_count == 0)
{
m_skin.skinChanged("");
m_model.modelChanged("");
m_entity.detach(m_keyObservers);
m_entity.instanceDetach(path_find_mapfile(path.begin(), path.end()));
m_filter.instanceDetach();
}
}
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_entity.attach( m_keyObservers );
m_model.modelChanged( m_entity.getEntityClass().modelpath() );
m_skin.skinChanged( m_entity.getEntityClass().skin() );
}
}
void instanceDetach( const scene::Path& path ){
if ( --m_instanceCounter.m_count == 0 ) {
m_skin.skinChanged( "" );
m_model.modelChanged( "" );
m_entity.detach( m_keyObservers );
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;
}
EntityKeyValues& getEntity(){
return m_entity;
}
const EntityKeyValues& getEntity() const {
return m_entity;
}
scene::Traversable& getTraversable()
{
return m_model.getTraversable();
}
Namespaced& getNamespaced()
{
return m_nameKeys;
}
Nameable& getNameable()
{
return m_named;
}
TransformNode& getTransformNode()
{
return m_transform;
}
ModelSkin& getModelSkin()
{
return m_skin.get();
}
scene::Traversable& getTraversable(){
return m_model.getTraversable();
}
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_model.attach(observer);
}
void detach(scene::Traversable::Observer* observer)
{
m_model.detach(observer);
}
void attach( scene::Traversable::Observer* observer ){
m_model.attach( observer );
}
void detach( scene::Traversable::Observer* observer ){
m_model.detach( observer );
}
void renderSolid(Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld, bool selected) const
{
if(selected)
{
m_renderOrigin.render(renderer, volume, localToWorld);
}
void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld, bool selected ) const {
if ( selected ) {
m_renderOrigin.render( renderer, volume, localToWorld );
}
renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly);
}
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);
}
}
renderer.SetState( m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly );
}
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 translate(const Vector3& translation)
{
m_origin = origin_translated(m_origin, translation);
}
void rotate(const Quaternion& rotation)
{
if(g_gameType == eGameTypeDoom3)
{
rotation_rotate(m_rotation, rotation);
}
else
{
m_angle = angle_rotated(m_angle, 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;
if(g_gameType == eGameTypeDoom3)
{
rotation_assign(m_rotation, m_rotationKey.m_rotation);
}
else
{
m_angle = m_angleKey.m_angle;
}
}
void freezeTransform()
{
m_originKey.m_origin = m_origin;
m_originKey.write(&m_entity);
if(g_gameType == eGameTypeDoom3)
{
rotation_assign(m_rotationKey.m_rotation, m_rotation);
m_rotationKey.write(&m_entity);
}
else
{
m_angleKey.m_angle = m_angle;
m_angleKey.write(&m_entity);
}
}
void transformChanged()
{
revertTransform();
m_evaluateTransform();
updateTransform();
}
typedef MemberCaller<EclassModel, &EclassModel::transformChanged> TransformChangedCaller;
void translate( const Vector3& translation ){
m_origin = origin_translated( m_origin, translation );
}
void rotate( const Quaternion& rotation ){
if ( g_gameType == eGameTypeDoom3 ) {
rotation_rotate( m_rotation, rotation );
}
else
{
m_angle = angle_rotated( m_angle, 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;
if ( g_gameType == eGameTypeDoom3 ) {
rotation_assign( m_rotation, m_rotationKey.m_rotation );
}
else
{
m_angle = m_angleKey.m_angle;
}
}
void freezeTransform(){
m_originKey.m_origin = m_origin;
m_originKey.write( &m_entity );
if ( g_gameType == eGameTypeDoom3 ) {
rotation_assign( m_rotationKey.m_rotation, m_rotation );
m_rotationKey.write( &m_entity );
}
else
{
m_angleKey.m_angle = m_angle;
m_angleKey.write( &m_entity );
}
}
void transformChanged(){
revertTransform();
m_evaluateTransform();
updateTransform();
}
typedef MemberCaller<EclassModel, &EclassModel::transformChanged> TransformChangedCaller;
};
class EclassModelInstance : public TargetableInstance, public TransformModifier, public Renderable
{
class TypeCasts
{
InstanceTypeCastTable m_casts;
public:
TypeCasts()
{
m_casts = TargetableInstance::StaticTypeCasts::instance().get();
InstanceStaticCast<EclassModelInstance, Renderable>::install(m_casts);
InstanceStaticCast<EclassModelInstance, Transformable>::install(m_casts);
InstanceIdentityCast<EclassModelInstance>::install(m_casts);
}
InstanceTypeCastTable& get()
{
return m_casts;
}
};
EclassModel& m_contained;
class TypeCasts
{
InstanceTypeCastTable m_casts;
public:
typedef LazyStatic<TypeCasts> StaticTypeCasts;
TypeCasts(){
m_casts = TargetableInstance::StaticTypeCasts::instance().get();
InstanceStaticCast<EclassModelInstance, Renderable>::install( m_casts );
InstanceStaticCast<EclassModelInstance, Transformable>::install( m_casts );
InstanceIdentityCast<EclassModelInstance>::install( m_casts );
}
InstanceTypeCastTable& get(){
return m_casts;
}
};
STRING_CONSTANT(Name, "EclassModelInstance");
EclassModel& m_contained;
public:
typedef LazyStatic<TypeCasts> StaticTypeCasts;
EclassModelInstance(const scene::Path& path, scene::Instance* parent, EclassModel& contained) :
TargetableInstance(path, parent, this, StaticTypeCasts::instance().get(), contained.getEntity(), *this),
TransformModifier(EclassModel::TransformChangedCaller(contained), ApplyTransformCaller(*this)),
m_contained(contained)
{
m_contained.instanceAttach(Instance::path());
STRING_CONSTANT( Name, "EclassModelInstance" );
StaticRenderableConnectionLines::instance().attach(*this);
}
~EclassModelInstance()
{
StaticRenderableConnectionLines::instance().detach(*this);
EclassModelInstance( const scene::Path& path, scene::Instance* parent, EclassModel& contained ) :
TargetableInstance( path, parent, this, StaticTypeCasts::instance().get(), contained.getEntity(), *this ),
TransformModifier( EclassModel::TransformChangedCaller( contained ), ApplyTransformCaller( *this ) ),
m_contained( contained ){
m_contained.instanceAttach( Instance::path() );
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());
}
StaticRenderableConnectionLines::instance().attach( *this );
}
~EclassModelInstance(){
StaticRenderableConnectionLines::instance().detach( *this );
void evaluateTransform()
{
if(getType() == TRANSFORM_PRIMITIVE)
{
m_contained.translate(getTranslation());
m_contained.rotate(getRotation());
}
}
void applyTransform()
{
m_contained.revertTransform();
evaluateTransform();
m_contained.freezeTransform();
}
typedef MemberCaller<EclassModelInstance, &EclassModelInstance::applyTransform> ApplyTransformCaller;
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() );
}
void evaluateTransform(){
if ( getType() == TRANSFORM_PRIMITIVE ) {
m_contained.translate( getTranslation() );
m_contained.rotate( getRotation() );
}
}
void applyTransform(){
m_contained.revertTransform();
evaluateTransform();
m_contained.freezeTransform();
}
typedef MemberCaller<EclassModelInstance, &EclassModelInstance::applyTransform> ApplyTransformCaller;
};
class EclassModelNode :
public scene::Node::Symbiot,
public scene::Instantiable,
public scene::Cloneable,
public scene::Traversable::Observer
public scene::Node::Symbiot,
public scene::Instantiable,
public scene::Cloneable,
public scene::Traversable::Observer
{
class TypeCasts
{
NodeTypeCastTable m_casts;
public:
TypeCasts()
{
NodeStaticCast<EclassModelNode, scene::Instantiable>::install(m_casts);
NodeStaticCast<EclassModelNode, scene::Cloneable>::install(m_casts);
NodeContainedCast<EclassModelNode, scene::Traversable>::install(m_casts);
NodeContainedCast<EclassModelNode, Snappable>::install(m_casts);
NodeContainedCast<EclassModelNode, TransformNode>::install(m_casts);
NodeContainedCast<EclassModelNode, Entity>::install(m_casts);
NodeContainedCast<EclassModelNode, Nameable>::install(m_casts);
NodeContainedCast<EclassModelNode, Namespaced>::install(m_casts);
NodeContainedCast<EclassModelNode, ModelSkin>::install(m_casts);
}
NodeTypeCastTable& get()
{
return m_casts;
}
};
scene::Node m_node;
InstanceSet m_instances;
EclassModel m_contained;
void construct()
{
m_contained.attach(this);
}
void destroy()
{
m_contained.detach(this);
}
class TypeCasts
{
NodeTypeCastTable m_casts;
public:
typedef LazyStatic<TypeCasts> StaticTypeCasts;
scene::Traversable& get(NullType<scene::Traversable>)
{
return m_contained.getTraversable();
}
Snappable& get(NullType<Snappable>)
{
return m_contained;
}
TransformNode& get(NullType<TransformNode>)
{
return m_contained.getTransformNode();
}
Entity& get(NullType<Entity>)
{
return m_contained.getEntity();
}
Nameable& get(NullType<Nameable>)
{
return m_contained.getNameable();
}
Namespaced& get(NullType<Namespaced>)
{
return m_contained.getNamespaced();
}
ModelSkin& get(NullType<ModelSkin>)
{
return m_contained.getModelSkin();
}
EclassModelNode(EntityClass* eclass) :
m_node(this, this, StaticTypeCasts::instance().get()),
m_contained(eclass, m_node, InstanceSet::TransformChangedCaller(m_instances), InstanceSetEvaluateTransform<EclassModelInstance>::Caller(m_instances))
{
construct();
}
EclassModelNode(const EclassModelNode& 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), InstanceSetEvaluateTransform<EclassModelInstance>::Caller(m_instances))
{
construct();
}
~EclassModelNode()
{
destroy();
}
void release()
{
delete this;
}
scene::Node& node()
{
return m_node;
}
void insert(scene::Node& child)
{
m_instances.insert(child);
}
void erase(scene::Node& child)
{
m_instances.erase(child);
}
scene::Node& clone() const
{
return (new EclassModelNode(*this))->node();
}
scene::Instance* create(const scene::Path& path, scene::Instance* parent)
{
return new EclassModelInstance(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);
}
TypeCasts(){
NodeStaticCast<EclassModelNode, scene::Instantiable>::install( m_casts );
NodeStaticCast<EclassModelNode, scene::Cloneable>::install( m_casts );
NodeContainedCast<EclassModelNode, scene::Traversable>::install( m_casts );
NodeContainedCast<EclassModelNode, Snappable>::install( m_casts );
NodeContainedCast<EclassModelNode, TransformNode>::install( m_casts );
NodeContainedCast<EclassModelNode, Entity>::install( m_casts );
NodeContainedCast<EclassModelNode, Nameable>::install( m_casts );
NodeContainedCast<EclassModelNode, Namespaced>::install( m_casts );
NodeContainedCast<EclassModelNode, ModelSkin>::install( m_casts );
}
NodeTypeCastTable& get(){
return m_casts;
}
};
scene::Node& New_EclassModel(EntityClass* eclass)
{
return (new EclassModelNode(eclass))->node();
scene::Node m_node;
InstanceSet m_instances;
EclassModel m_contained;
void construct(){
m_contained.attach( this );
}
void destroy(){
m_contained.detach( this );
}
public:
typedef LazyStatic<TypeCasts> StaticTypeCasts;
scene::Traversable& get( NullType<scene::Traversable>){
return m_contained.getTraversable();
}
Snappable& get( NullType<Snappable>){
return m_contained;
}
TransformNode& get( NullType<TransformNode>){
return m_contained.getTransformNode();
}
Entity& get( NullType<Entity>){
return m_contained.getEntity();
}
Nameable& get( NullType<Nameable>){
return m_contained.getNameable();
}
Namespaced& get( NullType<Namespaced>){
return m_contained.getNamespaced();
}
ModelSkin& get( NullType<ModelSkin>){
return m_contained.getModelSkin();
}
EclassModelNode( EntityClass* eclass ) :
m_node( this, this, StaticTypeCasts::instance().get() ),
m_contained( eclass, m_node, InstanceSet::TransformChangedCaller( m_instances ), InstanceSetEvaluateTransform<EclassModelInstance>::Caller( m_instances ) ){
construct();
}
EclassModelNode( const EclassModelNode& 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 ), InstanceSetEvaluateTransform<EclassModelInstance>::Caller( m_instances ) ){
construct();
}
~EclassModelNode(){
destroy();
}
void release(){
delete this;
}
scene::Node& node(){
return m_node;
}
void insert( scene::Node& child ){
m_instances.insert( child );
}
void erase( scene::Node& child ){
m_instances.erase( child );
}
scene::Node& clone() const {
return ( new EclassModelNode( *this ) )->node();
}
scene::Instance* create( const scene::Path& path, scene::Instance* parent ){
return new EclassModelInstance( 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 );
}
};
scene::Node& New_EclassModel( EntityClass* eclass ){
return ( new EclassModelNode( eclass ) )->node();
}

View File

@@ -1,34 +1,34 @@
/*
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
*/
#if !defined(INCLUDED_ECLASSMODEL_H)
#if !defined( INCLUDED_ECLASSMODEL_H )
#define INCLUDED_ECLASSMODEL_H
namespace scene
{
class Node;
class Node;
};
class EntityClass;
scene::Node& New_EclassModel(EntityClass* eclass);
scene::Node& New_EclassModel( EntityClass* eclass );
#include "entity.h"

View File

@@ -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
*/
#include "entity.h"
@@ -48,73 +48,62 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
EGameType g_gameType;
inline scene::Node& entity_for_eclass(EntityClass* eclass)
{
if((string_compare_nocase_n(eclass->name(), "misc_", 5) == 0 && string_equal_nocase(eclass->name() + string_length(eclass->name()) - 5, "model")) // misc_*model (also misc_model) // TODO make classname_* wrapper functions for this
|| classname_equal(eclass->name(), "model_static"))
{
return New_MiscModel(eclass);
}
else if(classname_equal(eclass->name(), "light")
|| classname_equal(eclass->name(), "lightJunior"))
{
return New_Light(eclass);
}
if(!eclass->fixedsize)
{
if(g_gameType == eGameTypeDoom3)
{
return New_Doom3Group(eclass);
}
else
{
return New_Group(eclass);
}
}
else if(!string_empty(eclass->modelpath()))
{
return New_EclassModel(eclass);
}
else
{
return New_GenericEntity(eclass);
}
inline scene::Node& entity_for_eclass( EntityClass* eclass ){
if ( ( string_compare_nocase_n( eclass->name(), "misc_", 5 ) == 0 && string_equal_nocase( eclass->name() + string_length( eclass->name() ) - 5, "model" ) ) // misc_*model (also misc_model) // TODO make classname_* wrapper functions for this
|| classname_equal( eclass->name(), "model_static" ) ) {
return New_MiscModel( eclass );
}
else if ( classname_equal( eclass->name(), "light" )
|| classname_equal( eclass->name(), "lightJunior" ) ) {
return New_Light( eclass );
}
if ( !eclass->fixedsize ) {
if ( g_gameType == eGameTypeDoom3 ) {
return New_Doom3Group( eclass );
}
else
{
return New_Group( eclass );
}
}
else if ( !string_empty( eclass->modelpath() ) ) {
return New_EclassModel( eclass );
}
else
{
return New_GenericEntity( eclass );
}
}
void Entity_setName(Entity& entity, const char* name)
{
entity.setKeyValue("name", name);
void Entity_setName( Entity& entity, const char* name ){
entity.setKeyValue( "name", name );
}
typedef ReferenceCaller1<Entity, const char*, Entity_setName> EntitySetNameCaller;
inline Namespaced* Node_getNamespaced(scene::Node& node)
{
return NodeTypeCast<Namespaced>::cast(node);
inline Namespaced* Node_getNamespaced( scene::Node& node ){
return NodeTypeCast<Namespaced>::cast( node );
}
inline scene::Node& node_for_eclass(EntityClass* eclass)
{
scene::Node& node = entity_for_eclass(eclass);
Node_getEntity(node)->setKeyValue("classname", eclass->name());
inline scene::Node& node_for_eclass( EntityClass* eclass ){
scene::Node& node = entity_for_eclass( eclass );
Node_getEntity( node )->setKeyValue( "classname", eclass->name() );
if(g_gameType == eGameTypeDoom3
&& string_not_empty(eclass->name())
&& !string_equal(eclass->name(), "worldspawn")
&& !string_equal(eclass->name(), "UNKNOWN_CLASS"))
{
char buffer[1024];
strcpy(buffer, eclass->name());
strcat(buffer, "_1");
GlobalNamespace().makeUnique(buffer, EntitySetNameCaller(*Node_getEntity(node)));
}
if ( g_gameType == eGameTypeDoom3
&& string_not_empty( eclass->name() )
&& !string_equal( eclass->name(), "worldspawn" )
&& !string_equal( eclass->name(), "UNKNOWN_CLASS" ) ) {
char buffer[1024];
strcpy( buffer, eclass->name() );
strcat( buffer, "_1" );
GlobalNamespace().makeUnique( buffer, EntitySetNameCaller( *Node_getEntity( node ) ) );
}
Namespaced* namespaced = Node_getNamespaced(node);
if(namespaced != 0)
{
namespaced->setNamespace(GlobalNamespace());
}
Namespaced* namespaced = Node_getNamespaced( node );
if ( namespaced != 0 ) {
namespaced->setNamespace( GlobalNamespace() );
}
return node;
return node;
}
EntityCreator::KeyValueChangedFunc EntityKeyValues::m_entityKeyValueChanged = 0;
@@ -129,281 +118,246 @@ bool g_lightRadii = false;
class ConnectEntities
{
public:
Entity* m_e1;
Entity* m_e2;
int m_index;
ConnectEntities(Entity* e1, Entity* e2, int index) : m_e1(e1), m_e2(e2), m_index(index)
{
}
const char *keyname()
{
StringOutputStream key(16);
if(m_index <= 0)
return "target";
if(m_index == 1)
return "killtarget";
key << "target" << m_index;
return key.c_str();
}
void connect(const char* name)
{
m_e1->setKeyValue(keyname(), name);
m_e2->setKeyValue("targetname", name);
}
typedef MemberCaller1<ConnectEntities, const char*, &ConnectEntities::connect> ConnectCaller;
Entity* m_e1;
Entity* m_e2;
int m_index;
ConnectEntities( Entity* e1, Entity* e2, int index ) : m_e1( e1 ), m_e2( e2 ), m_index( index ){
}
const char *keyname(){
StringOutputStream key( 16 );
if ( m_index <= 0 ) {
return "target";
}
if ( m_index == 1 ) {
return "killtarget";
}
key << "target" << m_index;
return key.c_str();
}
void connect( const char* name ){
m_e1->setKeyValue( keyname(), name );
m_e2->setKeyValue( "targetname", name );
}
typedef MemberCaller1<ConnectEntities, const char*, &ConnectEntities::connect> ConnectCaller;
};
inline Entity* ScenePath_getEntity(const scene::Path& path)
{
Entity* entity = Node_getEntity(path.top());
if(entity == 0)
{
entity = Node_getEntity(path.parent());
}
return entity;
inline Entity* ScenePath_getEntity( const scene::Path& path ){
Entity* entity = Node_getEntity( path.top() );
if ( entity == 0 ) {
entity = Node_getEntity( path.parent() );
}
return entity;
}
class Quake3EntityCreator : public EntityCreator
{
public:
scene::Node& createEntity(EntityClass* eclass)
{
return node_for_eclass(eclass);
}
void setKeyValueChangedFunc(KeyValueChangedFunc func)
{
EntityKeyValues::setKeyValueChangedFunc(func);
}
void setCounter(Counter* counter)
{
EntityKeyValues::setCounter(counter);
}
void connectEntities(const scene::Path& path, const scene::Path& targetPath, int index)
{
Entity* e1 = ScenePath_getEntity(path);
Entity* e2 = ScenePath_getEntity(targetPath);
scene::Node& createEntity( EntityClass* eclass ){
return node_for_eclass( eclass );
}
void setKeyValueChangedFunc( KeyValueChangedFunc func ){
EntityKeyValues::setKeyValueChangedFunc( func );
}
void setCounter( Counter* counter ){
EntityKeyValues::setCounter( counter );
}
void connectEntities( const scene::Path& path, const scene::Path& targetPath, int index ){
Entity* e1 = ScenePath_getEntity( path );
Entity* e2 = ScenePath_getEntity( targetPath );
if(e1 == 0 || e2 == 0)
{
globalErrorStream() << "entityConnectSelected: both of the selected instances must be an entity\n";
return;
}
if(e1 == e2)
{
globalErrorStream() << "entityConnectSelected: the selected instances must not both be from the same entity\n";
return;
}
UndoableCommand undo("entityConnectSelected");
if(g_gameType == eGameTypeDoom3)
{
StringOutputStream key(16);
if(index >= 0)
{
key << "target";
if(index != 0)
{
key << index;
}
e1->setKeyValue(key.c_str(), e2->getKeyValue("name"));
key.clear();
}
else
{
for(unsigned int i = 0; ; ++i)
{
key << "target";
if(i != 0)
{
key << i;
}
const char* value = e1->getKeyValue(key.c_str());
if(string_empty(value))
{
e1->setKeyValue(key.c_str(), e2->getKeyValue("name"));
break;
}
key.clear();
if ( e1 == 0 || e2 == 0 ) {
globalErrorStream() << "entityConnectSelected: both of the selected instances must be an entity\n";
return;
}
}
}
else
{
ConnectEntities connector(e1, e2, index);
const char* value = e2->getKeyValue("targetname");
if(!string_empty(value))
{
connector.connect(value);
}
else
{
const char* type = e2->getKeyValue("classname");
if(string_empty(type))
{
type = "t";
}
StringOutputStream key(64);
key << type << "1";
GlobalNamespace().makeUnique(key.c_str(), ConnectEntities::ConnectCaller(connector));
}
}
SceneChangeNotify();
}
void setLightRadii(bool lightRadii)
{
g_lightRadii = lightRadii;
}
bool getLightRadii()
{
return g_lightRadii;
}
void setShowNames(bool showNames)
{
g_showNames = showNames;
}
bool getShowNames()
{
return g_showNames;
}
void setShowAngles(bool showAngles)
{
g_showAngles = showAngles;
}
bool getShowAngles()
{
return g_showAngles;
}
if ( e1 == e2 ) {
globalErrorStream() << "entityConnectSelected: the selected instances must not both be from the same entity\n";
return;
}
void printStatistics() const
{
StringPool_analyse(EntityKeyValues::getPool());
}
UndoableCommand undo( "entityConnectSelected" );
if ( g_gameType == eGameTypeDoom3 ) {
StringOutputStream key( 16 );
if ( index >= 0 ) {
key << "target";
if ( index != 0 ) {
key << index;
}
e1->setKeyValue( key.c_str(), e2->getKeyValue( "name" ) );
key.clear();
}
else
{
for ( unsigned int i = 0; ; ++i )
{
key << "target";
if ( i != 0 ) {
key << i;
}
const char* value = e1->getKeyValue( key.c_str() );
if ( string_empty( value ) ) {
e1->setKeyValue( key.c_str(), e2->getKeyValue( "name" ) );
break;
}
key.clear();
}
}
}
else
{
ConnectEntities connector( e1, e2, index );
const char* value = e2->getKeyValue( "targetname" );
if ( !string_empty( value ) ) {
connector.connect( value );
}
else
{
const char* type = e2->getKeyValue( "classname" );
if ( string_empty( type ) ) {
type = "t";
}
StringOutputStream key( 64 );
key << type << "1";
GlobalNamespace().makeUnique( key.c_str(), ConnectEntities::ConnectCaller( connector ) );
}
}
SceneChangeNotify();
}
void setLightRadii( bool lightRadii ){
g_lightRadii = lightRadii;
}
bool getLightRadii(){
return g_lightRadii;
}
void setShowNames( bool showNames ){
g_showNames = showNames;
}
bool getShowNames(){
return g_showNames;
}
void setShowAngles( bool showAngles ){
g_showAngles = showAngles;
}
bool getShowAngles(){
return g_showAngles;
}
void printStatistics() const {
StringPool_analyse( EntityKeyValues::getPool() );
}
};
Quake3EntityCreator g_Quake3EntityCreator;
EntityCreator& GetEntityCreator()
{
return g_Quake3EntityCreator;
EntityCreator& GetEntityCreator(){
return g_Quake3EntityCreator;
}
class filter_entity_classname : public EntityFilter
{
const char* m_classname;
const char* m_classname;
public:
filter_entity_classname(const char* classname) : m_classname(classname)
{
}
bool filter(const Entity& entity) const
{
return string_equal(entity.getKeyValue("classname"), m_classname);
}
filter_entity_classname( const char* classname ) : m_classname( classname ){
}
bool filter( const Entity& entity ) const {
return string_equal( entity.getKeyValue( "classname" ), m_classname );
}
};
class filter_entity_classgroup : public EntityFilter
{
const char* m_classgroup;
std::size_t m_length;
const char* m_classgroup;
std::size_t m_length;
public:
filter_entity_classgroup(const char* classgroup) : m_classgroup(classgroup), m_length(string_length(m_classgroup))
{
}
bool filter(const Entity& entity) const
{
return string_equal_n(entity.getKeyValue("classname"), m_classgroup, m_length);
}
filter_entity_classgroup( const char* classgroup ) : m_classgroup( classgroup ), m_length( string_length( m_classgroup ) ){
}
bool filter( const Entity& entity ) const {
return string_equal_n( entity.getKeyValue( "classname" ), m_classgroup, m_length );
}
};
filter_entity_classname g_filter_entity_world("worldspawn");
filter_entity_classname g_filter_entity_func_group("func_group");
filter_entity_classname g_filter_entity_light("light");
filter_entity_classname g_filter_entity_misc_model("misc_model");
filter_entity_classname g_filter_entity_misc_gamemodel("misc_gamemodel");
filter_entity_classgroup g_filter_entity_trigger("trigger_");
filter_entity_classgroup g_filter_entity_path("path_");
filter_entity_classname g_filter_entity_world( "worldspawn" );
filter_entity_classname g_filter_entity_func_group( "func_group" );
filter_entity_classname g_filter_entity_light( "light" );
filter_entity_classname g_filter_entity_misc_model( "misc_model" );
filter_entity_classname g_filter_entity_misc_gamemodel( "misc_gamemodel" );
filter_entity_classgroup g_filter_entity_trigger( "trigger_" );
filter_entity_classgroup g_filter_entity_path( "path_" );
class filter_entity_doom3model : public EntityFilter
{
public:
bool filter(const Entity& entity) const
{
return string_equal(entity.getKeyValue("classname"), "func_static")
&& !string_equal(entity.getKeyValue("model"), entity.getKeyValue("name"));
}
bool filter( const Entity& entity ) const {
return string_equal( entity.getKeyValue( "classname" ), "func_static" )
&& !string_equal( entity.getKeyValue( "model" ), entity.getKeyValue( "name" ) );
}
};
filter_entity_doom3model g_filter_entity_doom3model;
void Entity_InitFilters()
{
add_entity_filter(g_filter_entity_world, EXCLUDE_WORLD);
add_entity_filter(g_filter_entity_func_group, EXCLUDE_WORLD);
add_entity_filter(g_filter_entity_world, EXCLUDE_ENT, true);
add_entity_filter(g_filter_entity_trigger, EXCLUDE_TRIGGERS);
add_entity_filter(g_filter_entity_misc_model, EXCLUDE_MODELS);
add_entity_filter(g_filter_entity_misc_gamemodel, EXCLUDE_MODELS);
add_entity_filter(g_filter_entity_doom3model, EXCLUDE_MODELS);
add_entity_filter(g_filter_entity_light, EXCLUDE_LIGHTS);
add_entity_filter(g_filter_entity_path, EXCLUDE_PATHS);
void Entity_InitFilters(){
add_entity_filter( g_filter_entity_world, EXCLUDE_WORLD );
add_entity_filter( g_filter_entity_func_group, EXCLUDE_WORLD );
add_entity_filter( g_filter_entity_world, EXCLUDE_ENT, true );
add_entity_filter( g_filter_entity_trigger, EXCLUDE_TRIGGERS );
add_entity_filter( g_filter_entity_misc_model, EXCLUDE_MODELS );
add_entity_filter( g_filter_entity_misc_gamemodel, EXCLUDE_MODELS );
add_entity_filter( g_filter_entity_doom3model, EXCLUDE_MODELS );
add_entity_filter( g_filter_entity_light, EXCLUDE_LIGHTS );
add_entity_filter( g_filter_entity_path, EXCLUDE_PATHS );
}
#include "preferencesystem.h"
void Entity_Construct(EGameType gameType)
{
g_gameType = gameType;
if(g_gameType == eGameTypeDoom3)
{
g_targetable_nameKey = "name";
void Entity_Construct( EGameType gameType ){
g_gameType = gameType;
if ( g_gameType == eGameTypeDoom3 ) {
g_targetable_nameKey = "name";
Static<KeyIsName>::instance().m_keyIsName = keyIsNameDoom3;
Static<KeyIsName>::instance().m_nameKey = "name";
}
else
{
Static<KeyIsName>::instance().m_keyIsName = keyIsNameQuake3;
Static<KeyIsName>::instance().m_nameKey = "targetname";
}
Static<KeyIsName>::instance().m_keyIsName = keyIsNameDoom3;
Static<KeyIsName>::instance().m_nameKey = "name";
}
else
{
Static<KeyIsName>::instance().m_keyIsName = keyIsNameQuake3;
Static<KeyIsName>::instance().m_nameKey = "targetname";
}
GlobalPreferenceSystem().registerPreference("SI_ShowNames", BoolImportStringCaller(g_showNames), BoolExportStringCaller(g_showNames));
GlobalPreferenceSystem().registerPreference("SI_ShowAngles", BoolImportStringCaller(g_showAngles), BoolExportStringCaller(g_showAngles));
GlobalPreferenceSystem().registerPreference("NewLightStyle", BoolImportStringCaller(g_newLightDraw), BoolExportStringCaller(g_newLightDraw));
GlobalPreferenceSystem().registerPreference("LightRadiuses", BoolImportStringCaller(g_lightRadii), BoolExportStringCaller(g_lightRadii));
GlobalPreferenceSystem().registerPreference( "SI_ShowNames", BoolImportStringCaller( g_showNames ), BoolExportStringCaller( g_showNames ) );
GlobalPreferenceSystem().registerPreference( "SI_ShowAngles", BoolImportStringCaller( g_showAngles ), BoolExportStringCaller( g_showAngles ) );
GlobalPreferenceSystem().registerPreference( "NewLightStyle", BoolImportStringCaller( g_newLightDraw ), BoolExportStringCaller( g_newLightDraw ) );
GlobalPreferenceSystem().registerPreference( "LightRadiuses", BoolImportStringCaller( g_lightRadii ), BoolExportStringCaller( g_lightRadii ) );
Entity_InitFilters();
LightType lightType = LIGHTTYPE_DEFAULT;
if(g_gameType == eGameTypeRTCW)
{
lightType = LIGHTTYPE_RTCW;
}
else if(g_gameType == eGameTypeDoom3)
{
lightType = LIGHTTYPE_DOOM3;
}
Light_Construct(lightType);
MiscModel_construct();
Doom3Group_construct();
Entity_InitFilters();
LightType lightType = LIGHTTYPE_DEFAULT;
if ( g_gameType == eGameTypeRTCW ) {
lightType = LIGHTTYPE_RTCW;
}
else if ( g_gameType == eGameTypeDoom3 ) {
lightType = LIGHTTYPE_DOOM3;
}
Light_Construct( lightType );
MiscModel_construct();
Doom3Group_construct();
RenderablePivot::StaticShader::instance() = GlobalShaderCache().capture("$PIVOT");
RenderablePivot::StaticShader::instance() = GlobalShaderCache().capture( "$PIVOT" );
GlobalShaderCache().attachRenderable(StaticRenderableConnectionLines::instance());
GlobalShaderCache().attachRenderable( StaticRenderableConnectionLines::instance() );
}
void Entity_Destroy()
{
GlobalShaderCache().detachRenderable(StaticRenderableConnectionLines::instance());
void Entity_Destroy(){
GlobalShaderCache().detachRenderable( StaticRenderableConnectionLines::instance() );
GlobalShaderCache().release("$PIVOT");
GlobalShaderCache().release( "$PIVOT" );
Doom3Group_destroy();
MiscModel_destroy();
Light_Destroy();
Doom3Group_destroy();
MiscModel_destroy();
Light_Destroy();
}

View File

@@ -1,25 +1,25 @@
/*
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
*/
#if !defined(INCLUDED_ENTITY_H)
#if !defined( INCLUDED_ENTITY_H )
#define INCLUDED_ENTITY_H
class EntityCreator;
@@ -27,15 +27,15 @@ EntityCreator& GetEntityCreator();
enum EGameType
{
eGameTypeQuake3,
eGameTypeRTCW,
eGameTypeDoom3,
eGameTypeQuake3,
eGameTypeRTCW,
eGameTypeDoom3,
};
extern EGameType g_gameType;
class FilterSystem;
void Entity_Construct(EGameType gameType = eGameTypeQuake3);
void Entity_Construct( EGameType gameType = eGameTypeQuake3 );
void Entity_Destroy();
extern bool g_showNames;

View File

@@ -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
*/
#include "filters.h"
@@ -27,46 +27,38 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
class EntityFilterWrapper : public Filter
{
bool m_active;
bool m_invert;
EntityFilter& m_filter;
bool m_active;
bool m_invert;
EntityFilter& m_filter;
public:
EntityFilterWrapper(EntityFilter& filter, bool invert) : m_invert(invert), m_filter(filter)
{
}
void setActive(bool active)
{
m_active = active;
}
bool active()
{
return m_active;
}
bool filter(const Entity& entity)
{
return m_invert ^ m_filter.filter(entity);
}
EntityFilterWrapper( EntityFilter& filter, bool invert ) : m_invert( invert ), m_filter( filter ){
}
void setActive( bool active ){
m_active = active;
}
bool active(){
return m_active;
}
bool filter( const Entity& entity ){
return m_invert ^ m_filter.filter( entity );
}
};
typedef std::list<EntityFilterWrapper> EntityFilters;
EntityFilters g_entityFilters;
void add_entity_filter(EntityFilter& filter, int mask, bool invert)
{
g_entityFilters.push_back(EntityFilterWrapper(filter, invert));
GlobalFilterSystem().addFilter(g_entityFilters.back(), mask);
void add_entity_filter( EntityFilter& filter, int mask, bool invert ){
g_entityFilters.push_back( EntityFilterWrapper( filter, invert ) );
GlobalFilterSystem().addFilter( g_entityFilters.back(), mask );
}
bool entity_filtered(Entity& entity)
{
for(EntityFilters::iterator i = g_entityFilters.begin(); i != g_entityFilters.end(); ++i)
{
if((*i).active() && (*i).filter(entity))
{
return true;
}
}
return false;
bool entity_filtered( Entity& entity ){
for ( EntityFilters::iterator i = g_entityFilters.begin(); i != g_entityFilters.end(); ++i )
{
if ( ( *i ).active() && ( *i ).filter( entity ) ) {
return true;
}
}
return false;
}

View File

@@ -1,25 +1,25 @@
/*
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
*/
#if !defined(INCLUDED_FILTERS_H)
#if !defined( INCLUDED_FILTERS_H )
#define INCLUDED_FILTERS_H
#include "ifilter.h"
@@ -32,51 +32,44 @@ class Entity;
class EntityFilter
{
public:
virtual bool filter(const Entity& entity) const = 0;
virtual bool filter( const Entity& entity ) const = 0;
};
bool entity_filtered(Entity& entity);
void add_entity_filter(EntityFilter& filter, int mask, bool invert = false);
bool entity_filtered( Entity& entity );
void add_entity_filter( EntityFilter& filter, int mask, bool invert = false );
class ClassnameFilter : public Filterable
{
scene::Node& m_node;
scene::Node& m_node;
public:
Entity& m_entity;
Entity& m_entity;
ClassnameFilter(Entity& entity, scene::Node& node) : m_node(node), m_entity(entity)
{
}
~ClassnameFilter()
{
}
ClassnameFilter( Entity& entity, scene::Node& node ) : m_node( node ), m_entity( entity ){
}
~ClassnameFilter(){
}
void instanceAttach()
{
GlobalFilterSystem().registerFilterable(*this);
}
void instanceDetach()
{
GlobalFilterSystem().unregisterFilterable(*this);
}
void instanceAttach(){
GlobalFilterSystem().registerFilterable( *this );
}
void instanceDetach(){
GlobalFilterSystem().unregisterFilterable( *this );
}
void updateFiltered()
{
if(entity_filtered(m_entity))
{
m_node.enable(scene::Node::eFiltered);
}
else
{
m_node.disable(scene::Node::eFiltered);
}
}
void updateFiltered(){
if ( entity_filtered( m_entity ) ) {
m_node.enable( scene::Node::eFiltered );
}
else
{
m_node.disable( scene::Node::eFiltered );
}
}
void classnameChanged(const char* value)
{
updateFiltered();
}
typedef MemberCaller1<ClassnameFilter, const char*, &ClassnameFilter::classnameChanged> ClassnameChangedCaller;
void classnameChanged( const char* value ){
updateFiltered();
}
typedef MemberCaller1<ClassnameFilter, const char*, &ClassnameFilter::classnameChanged> ClassnameChangedCaller;
};
#endif

View File

@@ -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 entity which has a fixed size specified in its entity-definition and does not display a model (e.g. info_player_start).
@@ -53,444 +53,382 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
class RenderableArrow : public OpenGLRenderable
{
const Vector3& m_origin;
const Vector3& m_angles;
const Vector3& m_origin;
const Vector3& m_angles;
public:
RenderableArrow(const Vector3& origin, const Vector3& angles)
: m_origin(origin), m_angles(angles)
{
}
RenderableArrow( const Vector3& origin, const Vector3& angles )
: m_origin( origin ), m_angles( angles ){
}
void render(RenderStateFlags state) const
{
Matrix4 mat = matrix4_rotation_for_euler_xyz_degrees(m_angles);
arrow_draw(m_origin, matrix4_transformed_direction(mat, Vector3(1, 0, 0)), matrix4_transformed_direction(mat, Vector3(0, 1, 0)), matrix4_transformed_direction(mat, Vector3(0, 0, 1)));
}
void render( RenderStateFlags state ) const {
Matrix4 mat = matrix4_rotation_for_euler_xyz_degrees( m_angles );
arrow_draw( m_origin, matrix4_transformed_direction( mat, Vector3( 1, 0, 0 ) ), matrix4_transformed_direction( mat, Vector3( 0, 1, 0 ) ), matrix4_transformed_direction( mat, Vector3( 0, 0, 1 ) ) );
}
};
inline void read_aabb(AABB& aabb, const EntityClass& eclass)
{
aabb = aabb_for_minmax(eclass.mins, eclass.maxs);
inline void read_aabb( AABB& aabb, const EntityClass& eclass ){
aabb = aabb_for_minmax( eclass.mins, eclass.maxs );
}
class GenericEntity :
public Cullable,
public Bounded,
public Snappable
public Cullable,
public Bounded,
public Snappable
{
EntityKeyValues m_entity;
KeyObserverMap m_keyObservers;
MatrixTransform m_transform;
EntityKeyValues m_entity;
KeyObserverMap m_keyObservers;
MatrixTransform m_transform;
OriginKey m_originKey;
Vector3 m_origin;
AnglesKey m_anglesKey;
Vector3 m_angles;
OriginKey m_originKey;
Vector3 m_origin;
AnglesKey m_anglesKey;
Vector3 m_angles;
ClassnameFilter m_filter;
NamedEntity m_named;
NameKeys m_nameKeys;
ClassnameFilter m_filter;
NamedEntity m_named;
NameKeys m_nameKeys;
AABB m_aabb_local;
AABB m_aabb_local;
RenderableArrow m_arrow;
RenderableSolidAABB m_aabb_solid;
RenderableWireframeAABB m_aabb_wire;
RenderableNamedEntity m_renderName;
RenderableArrow m_arrow;
RenderableSolidAABB m_aabb_solid;
RenderableWireframeAABB m_aabb_wire;
RenderableNamedEntity m_renderName;
Callback m_transformChanged;
Callback m_evaluateTransform;
Callback m_transformChanged;
Callback m_evaluateTransform;
void construct()
{
read_aabb(m_aabb_local, m_entity.getEntityClass());
void construct(){
read_aabb( m_aabb_local, m_entity.getEntityClass() );
m_keyObservers.insert("classname", ClassnameFilter::ClassnameChangedCaller(m_filter));
m_keyObservers.insert(Static<KeyIsName>::instance().m_nameKey, NamedEntity::IdentifierChangedCaller(m_named));
m_keyObservers.insert("angle", AnglesKey::AngleChangedCaller(m_anglesKey));
m_keyObservers.insert("angles", AnglesKey::AnglesChangedCaller(m_anglesKey));
m_keyObservers.insert("origin", OriginKey::OriginChangedCaller(m_originKey));
}
m_keyObservers.insert( "classname", ClassnameFilter::ClassnameChangedCaller( m_filter ) );
m_keyObservers.insert( Static<KeyIsName>::instance().m_nameKey, NamedEntity::IdentifierChangedCaller( m_named ) );
m_keyObservers.insert( "angle", AnglesKey::AngleChangedCaller( m_anglesKey ) );
m_keyObservers.insert( "angles", AnglesKey::AnglesChangedCaller( m_anglesKey ) );
m_keyObservers.insert( "origin", OriginKey::OriginChangedCaller( m_originKey ) );
}
// vc 2k5 compiler fix
// vc 2k5 compiler fix
#if _MSC_VER >= 1400
public:
public:
#endif
void updateTransform()
{
m_transform.localToParent() = g_matrix4_identity;
matrix4_translate_by_vec3(m_transform.localToParent(), m_origin);
m_transformChanged();
}
typedef MemberCaller<GenericEntity, &GenericEntity::updateTransform> UpdateTransformCaller;
void originChanged()
{
m_origin = m_originKey.m_origin;
updateTransform();
}
typedef MemberCaller<GenericEntity, &GenericEntity::originChanged> OriginChangedCaller;
void anglesChanged()
{
m_angles = m_anglesKey.m_angles;
updateTransform();
}
typedef MemberCaller<GenericEntity, &GenericEntity::anglesChanged> AnglesChangedCaller;
void updateTransform(){
m_transform.localToParent() = g_matrix4_identity;
matrix4_translate_by_vec3( m_transform.localToParent(), m_origin );
m_transformChanged();
}
typedef MemberCaller<GenericEntity, &GenericEntity::updateTransform> UpdateTransformCaller;
void originChanged(){
m_origin = m_originKey.m_origin;
updateTransform();
}
typedef MemberCaller<GenericEntity, &GenericEntity::originChanged> OriginChangedCaller;
void anglesChanged(){
m_angles = m_anglesKey.m_angles;
updateTransform();
}
typedef MemberCaller<GenericEntity, &GenericEntity::anglesChanged> AnglesChangedCaller;
public:
GenericEntity(EntityClass* eclass, scene::Node& node, const Callback& transformChanged, const Callback& evaluateTransform) :
m_entity(eclass),
m_originKey(OriginChangedCaller(*this)),
m_origin(ORIGINKEY_IDENTITY),
m_anglesKey(AnglesChangedCaller(*this)),
m_angles(ANGLESKEY_IDENTITY),
m_filter(m_entity, node),
m_named(m_entity),
m_nameKeys(m_entity),
m_arrow(m_aabb_local.origin, m_angles),
m_aabb_solid(m_aabb_local),
m_aabb_wire(m_aabb_local),
m_renderName(m_named, g_vector3_identity),
m_transformChanged(transformChanged),
m_evaluateTransform(evaluateTransform)
{
construct();
}
GenericEntity(const GenericEntity& other, scene::Node& node, const Callback& transformChanged, const Callback& evaluateTransform) :
m_entity(other.m_entity),
m_originKey(OriginChangedCaller(*this)),
m_origin(ORIGINKEY_IDENTITY),
m_anglesKey(AnglesChangedCaller(*this)),
m_angles(ANGLESKEY_IDENTITY),
m_filter(m_entity, node),
m_named(m_entity),
m_nameKeys(m_entity),
m_arrow(m_aabb_local.origin, m_angles),
m_aabb_solid(m_aabb_local),
m_aabb_wire(m_aabb_local),
m_renderName(m_named, g_vector3_identity),
m_transformChanged(transformChanged),
m_evaluateTransform(evaluateTransform)
{
construct();
}
GenericEntity( EntityClass* eclass, scene::Node& node, const Callback& transformChanged, const Callback& evaluateTransform ) :
m_entity( eclass ),
m_originKey( OriginChangedCaller( *this ) ),
m_origin( ORIGINKEY_IDENTITY ),
m_anglesKey( AnglesChangedCaller( *this ) ),
m_angles( ANGLESKEY_IDENTITY ),
m_filter( m_entity, node ),
m_named( m_entity ),
m_nameKeys( m_entity ),
m_arrow( m_aabb_local.origin, m_angles ),
m_aabb_solid( m_aabb_local ),
m_aabb_wire( m_aabb_local ),
m_renderName( m_named, g_vector3_identity ),
m_transformChanged( transformChanged ),
m_evaluateTransform( evaluateTransform ){
construct();
}
GenericEntity( const GenericEntity& other, scene::Node& node, const Callback& transformChanged, const Callback& evaluateTransform ) :
m_entity( other.m_entity ),
m_originKey( OriginChangedCaller( *this ) ),
m_origin( ORIGINKEY_IDENTITY ),
m_anglesKey( AnglesChangedCaller( *this ) ),
m_angles( ANGLESKEY_IDENTITY ),
m_filter( m_entity, node ),
m_named( m_entity ),
m_nameKeys( m_entity ),
m_arrow( m_aabb_local.origin, m_angles ),
m_aabb_solid( m_aabb_local ),
m_aabb_wire( m_aabb_local ),
m_renderName( m_named, g_vector3_identity ),
m_transformChanged( transformChanged ),
m_evaluateTransform( evaluateTransform ){
construct();
}
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_entity.attach(m_keyObservers);
}
}
void instanceDetach(const scene::Path& path)
{
if(--m_instanceCounter.m_count == 0)
{
m_entity.detach(m_keyObservers);
m_entity.instanceDetach(path_find_mapfile(path.begin(), path.end()));
m_filter.instanceDetach();
}
}
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_entity.attach( m_keyObservers );
}
}
void instanceDetach( const scene::Path& path ){
if ( --m_instanceCounter.m_count == 0 ) {
m_entity.detach( m_keyObservers );
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;
}
EntityKeyValues& getEntity(){
return m_entity;
}
const EntityKeyValues& getEntity() const {
return m_entity;
}
Namespaced& getNamespaced()
{
return m_nameKeys;
}
Nameable& getNameable()
{
return m_named;
}
TransformNode& getTransformNode()
{
return m_transform;
}
Namespaced& getNamespaced(){
return m_nameKeys;
}
Nameable& getNameable(){
return m_named;
}
TransformNode& getTransformNode(){
return m_transform;
}
const AABB& localAABB() const
{
return m_aabb_local;
}
const AABB& localAABB() const {
return m_aabb_local;
}
VolumeIntersectionValue intersectVolume(const VolumeTest& volume, const Matrix4& localToWorld) const
{
return volume.TestAABB(localAABB(), localToWorld);
}
VolumeIntersectionValue intersectVolume( const VolumeTest& volume, const Matrix4& localToWorld ) const {
return volume.TestAABB( localAABB(), localToWorld );
}
void renderArrow(Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld) const
{
if(g_showAngles)
{
renderer.addRenderable(m_arrow, localToWorld);
}
}
void renderSolid(Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld) const
{
renderer.SetState(m_entity.getEntityClass().m_state_fill, Renderer::eFullMaterials);
renderer.addRenderable(m_aabb_solid, localToWorld);
renderArrow(renderer, volume, localToWorld);
}
void renderWireframe(Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld) const
{
renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly);
renderer.addRenderable(m_aabb_wire, localToWorld);
renderArrow(renderer, volume, localToWorld);
if(g_showNames)
{
renderer.addRenderable(m_renderName, localToWorld);
}
}
void renderArrow( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const {
if ( g_showAngles ) {
renderer.addRenderable( m_arrow, localToWorld );
}
}
void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const {
renderer.SetState( m_entity.getEntityClass().m_state_fill, Renderer::eFullMaterials );
renderer.addRenderable( m_aabb_solid, localToWorld );
renderArrow( renderer, volume, localToWorld );
}
void renderWireframe( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const {
renderer.SetState( m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly );
renderer.addRenderable( m_aabb_wire, localToWorld );
renderArrow( renderer, volume, localToWorld );
if ( g_showNames ) {
renderer.addRenderable( m_renderName, localToWorld );
}
}
void testSelect(Selector& selector, SelectionTest& test, const Matrix4& localToWorld)
{
test.BeginMesh(localToWorld);
void testSelect( Selector& selector, SelectionTest& test, const Matrix4& localToWorld ){
test.BeginMesh( localToWorld );
SelectionIntersection best;
aabb_testselect(m_aabb_local, test, best);
if(best.valid())
{
selector.addIntersection(best);
}
}
SelectionIntersection best;
aabb_testselect( m_aabb_local, test, best );
if ( best.valid() ) {
selector.addIntersection( best );
}
}
void translate(const Vector3& translation)
{
m_origin = origin_translated(m_origin, translation);
}
void rotate(const Quaternion& rotation)
{
m_angles = angles_rotated(m_angles, 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;
m_angles = m_anglesKey.m_angles;
}
void freezeTransform()
{
m_originKey.m_origin = m_origin;
m_originKey.write(&m_entity);
m_anglesKey.m_angles = m_angles;
m_anglesKey.write(&m_entity);
}
void transformChanged()
{
revertTransform();
m_evaluateTransform();
updateTransform();
}
typedef MemberCaller<GenericEntity, &GenericEntity::transformChanged> TransformChangedCaller;
void translate( const Vector3& translation ){
m_origin = origin_translated( m_origin, translation );
}
void rotate( const Quaternion& rotation ){
m_angles = angles_rotated( m_angles, 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;
m_angles = m_anglesKey.m_angles;
}
void freezeTransform(){
m_originKey.m_origin = m_origin;
m_originKey.write( &m_entity );
m_anglesKey.m_angles = m_angles;
m_anglesKey.write( &m_entity );
}
void transformChanged(){
revertTransform();
m_evaluateTransform();
updateTransform();
}
typedef MemberCaller<GenericEntity, &GenericEntity::transformChanged> TransformChangedCaller;
};
class GenericEntityInstance :
public TargetableInstance,
public TransformModifier,
public Renderable,
public SelectionTestable
public TargetableInstance,
public TransformModifier,
public Renderable,
public SelectionTestable
{
class TypeCasts
{
InstanceTypeCastTable m_casts;
public:
TypeCasts()
{
m_casts = TargetableInstance::StaticTypeCasts::instance().get();
InstanceContainedCast<GenericEntityInstance, Bounded>::install(m_casts);
InstanceContainedCast<GenericEntityInstance, Cullable>::install(m_casts);
InstanceStaticCast<GenericEntityInstance, Renderable>::install(m_casts);
InstanceStaticCast<GenericEntityInstance, SelectionTestable>::install(m_casts);
InstanceStaticCast<GenericEntityInstance, Transformable>::install(m_casts);
InstanceIdentityCast<GenericEntityInstance>::install(m_casts);
}
InstanceTypeCastTable& get()
{
return m_casts;
}
};
class TypeCasts
{
InstanceTypeCastTable m_casts;
public:
TypeCasts(){
m_casts = TargetableInstance::StaticTypeCasts::instance().get();
InstanceContainedCast<GenericEntityInstance, Bounded>::install( m_casts );
InstanceContainedCast<GenericEntityInstance, Cullable>::install( m_casts );
InstanceStaticCast<GenericEntityInstance, Renderable>::install( m_casts );
InstanceStaticCast<GenericEntityInstance, SelectionTestable>::install( m_casts );
InstanceStaticCast<GenericEntityInstance, Transformable>::install( m_casts );
InstanceIdentityCast<GenericEntityInstance>::install( m_casts );
}
InstanceTypeCastTable& get(){
return m_casts;
}
};
GenericEntity& m_contained;
mutable AABB m_bounds;
GenericEntity& m_contained;
mutable AABB m_bounds;
public:
typedef LazyStatic<TypeCasts> StaticTypeCasts;
typedef LazyStatic<TypeCasts> StaticTypeCasts;
Bounded& get(NullType<Bounded>)
{
return m_contained;
}
Cullable& get(NullType<Cullable>)
{
return m_contained;
}
Bounded& get( NullType<Bounded>){
return m_contained;
}
Cullable& get( NullType<Cullable>){
return m_contained;
}
STRING_CONSTANT(Name, "GenericEntityInstance");
STRING_CONSTANT( Name, "GenericEntityInstance" );
GenericEntityInstance(const scene::Path& path, scene::Instance* parent, GenericEntity& contained) :
TargetableInstance(path, parent, this, StaticTypeCasts::instance().get(), contained.getEntity(), *this),
TransformModifier(GenericEntity::TransformChangedCaller(contained), ApplyTransformCaller(*this)),
m_contained(contained)
{
m_contained.instanceAttach(Instance::path());
GenericEntityInstance( const scene::Path& path, scene::Instance* parent, GenericEntity& contained ) :
TargetableInstance( path, parent, this, StaticTypeCasts::instance().get(), contained.getEntity(), *this ),
TransformModifier( GenericEntity::TransformChangedCaller( contained ), ApplyTransformCaller( *this ) ),
m_contained( contained ){
m_contained.instanceAttach( Instance::path() );
StaticRenderableConnectionLines::instance().attach(*this);
}
~GenericEntityInstance()
{
StaticRenderableConnectionLines::instance().detach(*this);
StaticRenderableConnectionLines::instance().attach( *this );
}
~GenericEntityInstance(){
StaticRenderableConnectionLines::instance().detach( *this );
m_contained.instanceDetach(Instance::path());
}
m_contained.instanceDetach( Instance::path() );
}
void renderSolid(Renderer& renderer, const VolumeTest& volume) const
{
m_contained.renderSolid(renderer, volume, Instance::localToWorld());
}
void renderWireframe(Renderer& renderer, const VolumeTest& volume) const
{
m_contained.renderWireframe(renderer, volume, Instance::localToWorld());
}
void renderSolid( Renderer& renderer, const VolumeTest& volume ) const {
m_contained.renderSolid( renderer, volume, Instance::localToWorld() );
}
void renderWireframe( Renderer& renderer, const VolumeTest& volume ) const {
m_contained.renderWireframe( renderer, volume, Instance::localToWorld() );
}
void testSelect(Selector& selector, SelectionTest& test)
{
m_contained.testSelect(selector, test, Instance::localToWorld());
}
void testSelect( Selector& selector, SelectionTest& test ){
m_contained.testSelect( selector, test, Instance::localToWorld() );
}
void evaluateTransform()
{
if(getType() == TRANSFORM_PRIMITIVE)
{
m_contained.translate(getTranslation());
m_contained.rotate(getRotation());
}
}
void applyTransform()
{
m_contained.revertTransform();
evaluateTransform();
m_contained.freezeTransform();
}
typedef MemberCaller<GenericEntityInstance, &GenericEntityInstance::applyTransform> ApplyTransformCaller;
void evaluateTransform(){
if ( getType() == TRANSFORM_PRIMITIVE ) {
m_contained.translate( getTranslation() );
m_contained.rotate( getRotation() );
}
}
void applyTransform(){
m_contained.revertTransform();
evaluateTransform();
m_contained.freezeTransform();
}
typedef MemberCaller<GenericEntityInstance, &GenericEntityInstance::applyTransform> ApplyTransformCaller;
};
class GenericEntityNode :
public scene::Node::Symbiot,
public scene::Instantiable,
public scene::Cloneable
public scene::Node::Symbiot,
public scene::Instantiable,
public scene::Cloneable
{
class TypeCasts
{
NodeTypeCastTable m_casts;
public:
TypeCasts()
{
NodeStaticCast<GenericEntityNode, scene::Instantiable>::install(m_casts);
NodeStaticCast<GenericEntityNode, scene::Cloneable>::install(m_casts);
NodeContainedCast<GenericEntityNode, Snappable>::install(m_casts);
NodeContainedCast<GenericEntityNode, TransformNode>::install(m_casts);
NodeContainedCast<GenericEntityNode, Entity>::install(m_casts);
NodeContainedCast<GenericEntityNode, Nameable>::install(m_casts);
NodeContainedCast<GenericEntityNode, Namespaced>::install(m_casts);
}
NodeTypeCastTable& get()
{
return m_casts;
}
};
InstanceSet m_instances;
scene::Node m_node;
GenericEntity m_contained;
class TypeCasts
{
NodeTypeCastTable m_casts;
public:
typedef LazyStatic<TypeCasts> StaticTypeCasts;
Snappable& get(NullType<Snappable>)
{
return m_contained;
}
TransformNode& get(NullType<TransformNode>)
{
return m_contained.getTransformNode();
}
Entity& get(NullType<Entity>)
{
return m_contained.getEntity();
}
Nameable& get(NullType<Nameable>)
{
return m_contained.getNameable();
}
Namespaced& get(NullType<Namespaced>)
{
return m_contained.getNamespaced();
}
GenericEntityNode(EntityClass* eclass) :
m_node(this, this, StaticTypeCasts::instance().get()),
m_contained(eclass, m_node, InstanceSet::TransformChangedCaller(m_instances), InstanceSetEvaluateTransform<GenericEntityInstance>::Caller(m_instances))
{
}
GenericEntityNode(const GenericEntityNode& other) :
scene::Node::Symbiot(other),
scene::Instantiable(other),
scene::Cloneable(other),
m_node(this, this, StaticTypeCasts::instance().get()),
m_contained(other.m_contained, m_node, InstanceSet::TransformChangedCaller(m_instances), InstanceSetEvaluateTransform<GenericEntityInstance>::Caller(m_instances))
{
}
void release()
{
delete this;
}
scene::Node& node()
{
return m_node;
}
scene::Node& clone() const
{
return (new GenericEntityNode(*this))->node();
}
scene::Instance* create(const scene::Path& path, scene::Instance* parent)
{
return new GenericEntityInstance(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);
}
TypeCasts(){
NodeStaticCast<GenericEntityNode, scene::Instantiable>::install( m_casts );
NodeStaticCast<GenericEntityNode, scene::Cloneable>::install( m_casts );
NodeContainedCast<GenericEntityNode, Snappable>::install( m_casts );
NodeContainedCast<GenericEntityNode, TransformNode>::install( m_casts );
NodeContainedCast<GenericEntityNode, Entity>::install( m_casts );
NodeContainedCast<GenericEntityNode, Nameable>::install( m_casts );
NodeContainedCast<GenericEntityNode, Namespaced>::install( m_casts );
}
NodeTypeCastTable& get(){
return m_casts;
}
};
scene::Node& New_GenericEntity(EntityClass* eclass)
{
return (new GenericEntityNode(eclass))->node();
InstanceSet m_instances;
scene::Node m_node;
GenericEntity m_contained;
public:
typedef LazyStatic<TypeCasts> StaticTypeCasts;
Snappable& get( NullType<Snappable>){
return m_contained;
}
TransformNode& get( NullType<TransformNode>){
return m_contained.getTransformNode();
}
Entity& get( NullType<Entity>){
return m_contained.getEntity();
}
Nameable& get( NullType<Nameable>){
return m_contained.getNameable();
}
Namespaced& get( NullType<Namespaced>){
return m_contained.getNamespaced();
}
GenericEntityNode( EntityClass* eclass ) :
m_node( this, this, StaticTypeCasts::instance().get() ),
m_contained( eclass, m_node, InstanceSet::TransformChangedCaller( m_instances ), InstanceSetEvaluateTransform<GenericEntityInstance>::Caller( m_instances ) ){
}
GenericEntityNode( const GenericEntityNode& other ) :
scene::Node::Symbiot( other ),
scene::Instantiable( other ),
scene::Cloneable( other ),
m_node( this, this, StaticTypeCasts::instance().get() ),
m_contained( other.m_contained, m_node, InstanceSet::TransformChangedCaller( m_instances ), InstanceSetEvaluateTransform<GenericEntityInstance>::Caller( m_instances ) ){
}
void release(){
delete this;
}
scene::Node& node(){
return m_node;
}
scene::Node& clone() const {
return ( new GenericEntityNode( *this ) )->node();
}
scene::Instance* create( const scene::Path& path, scene::Instance* parent ){
return new GenericEntityInstance( 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 );
}
};
scene::Node& New_GenericEntity( EntityClass* eclass ){
return ( new GenericEntityNode( eclass ) )->node();
}

View File

@@ -1,27 +1,27 @@
/*
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
*/
#if !defined(INCLUDED_GENERIC_H)
#if !defined( INCLUDED_GENERIC_H )
#define INCLUDED_GENERIC_H
scene::Node& New_GenericEntity(EntityClass* eclass);
scene::Node& New_GenericEntity( EntityClass* eclass );
#endif

View File

@@ -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 entity which does not have a fixed size specified in its entity-definition (except misc_model).
@@ -51,471 +51,401 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
class Group
{
EntityKeyValues m_entity;
KeyObserverMap m_keyObservers;
MatrixTransform m_transform;
TraversableNodeSet m_traverse;
EntityKeyValues m_entity;
KeyObserverMap m_keyObservers;
MatrixTransform m_transform;
TraversableNodeSet m_traverse;
ClassnameFilter m_filter;
NamedEntity m_named;
NameKeys m_nameKeys;
ClassnameFilter m_filter;
NamedEntity m_named;
NameKeys m_nameKeys;
OriginKey m_originKey;
Vector3 m_origin;
OriginKey m_originKey;
Vector3 m_origin;
RenderableNamedEntity m_renderName;
mutable Vector3 m_name_origin;
RenderableNamedEntity m_renderName;
mutable Vector3 m_name_origin;
Callback m_transformChanged;
Callback m_evaluateTransform;
Callback m_transformChanged;
Callback m_evaluateTransform;
void construct(){
m_keyObservers.insert( "classname", ClassnameFilter::ClassnameChangedCaller( m_filter ) );
m_keyObservers.insert( Static<KeyIsName>::instance().m_nameKey, NamedEntity::IdentifierChangedCaller( m_named ) );
m_keyObservers.insert( "origin", OriginKey::OriginChangedCaller( m_originKey ) );
}
void construct()
{
m_keyObservers.insert("classname", ClassnameFilter::ClassnameChangedCaller(m_filter));
m_keyObservers.insert(Static<KeyIsName>::instance().m_nameKey, NamedEntity::IdentifierChangedCaller(m_named));
m_keyObservers.insert("origin", OriginKey::OriginChangedCaller(m_originKey));
}
public:
Group(EntityClass* eclass, scene::Node& node, const Callback& transformChanged, const Callback& evaluateTransform) :
m_entity(eclass),
m_filter(m_entity, node),
m_named(m_entity),
m_nameKeys(m_entity),
m_originKey(OriginChangedCaller(*this)),
m_origin(ORIGINKEY_IDENTITY),
m_renderName(m_named, m_name_origin),
m_name_origin(g_vector3_identity),
m_transformChanged(transformChanged),
m_evaluateTransform(evaluateTransform)
{
construct();
}
Group(const Group& other, scene::Node& node, const Callback& transformChanged, const Callback& evaluateTransform) :
m_entity(other.m_entity),
m_filter(m_entity, node),
m_named(m_entity),
m_nameKeys(m_entity),
m_originKey(OriginChangedCaller(*this)),
m_origin(ORIGINKEY_IDENTITY),
m_renderName(m_named, g_vector3_identity),
m_transformChanged(transformChanged),
m_evaluateTransform(evaluateTransform)
{
construct();
}
Group( EntityClass* eclass, scene::Node& node, const Callback& transformChanged, const Callback& evaluateTransform ) :
m_entity( eclass ),
m_filter( m_entity, node ),
m_named( m_entity ),
m_nameKeys( m_entity ),
m_originKey( OriginChangedCaller( *this ) ),
m_origin( ORIGINKEY_IDENTITY ),
m_renderName( m_named, m_name_origin ),
m_name_origin( g_vector3_identity ),
m_transformChanged( transformChanged ),
m_evaluateTransform( evaluateTransform ){
construct();
}
Group( const Group& other, scene::Node& node, const Callback& transformChanged, const Callback& evaluateTransform ) :
m_entity( other.m_entity ),
m_filter( m_entity, node ),
m_named( m_entity ),
m_nameKeys( m_entity ),
m_originKey( OriginChangedCaller( *this ) ),
m_origin( ORIGINKEY_IDENTITY ),
m_renderName( m_named, g_vector3_identity ),
m_transformChanged( transformChanged ),
m_evaluateTransform( evaluateTransform ){
construct();
}
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_entity.attach(m_keyObservers);
}
}
void instanceDetach(const scene::Path& path)
{
if(--m_instanceCounter.m_count == 0)
{
m_entity.detach(m_keyObservers);
m_traverse.instanceDetach(path_find_mapfile(path.begin(), path.end()));
m_entity.instanceDetach(path_find_mapfile(path.begin(), path.end()));
m_filter.instanceDetach();
}
}
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_entity.attach( m_keyObservers );
}
}
void instanceDetach( const scene::Path& path ){
if ( --m_instanceCounter.m_count == 0 ) {
m_entity.detach( m_keyObservers );
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;
}
EntityKeyValues& getEntity(){
return m_entity;
}
const EntityKeyValues& getEntity() const {
return m_entity;
}
scene::Traversable& getTraversable()
{
return m_traverse;
}
Namespaced& getNamespaced()
{
return m_nameKeys;
}
Nameable& getNameable()
{
return m_named;
}
TransformNode& getTransformNode()
{
return m_transform;
}
scene::Traversable& getTraversable(){
return m_traverse;
}
Namespaced& getNamespaced(){
return m_nameKeys;
}
Nameable& getNameable(){
return m_named;
}
TransformNode& getTransformNode(){
return m_transform;
}
void attach(scene::Traversable::Observer* observer)
{
m_traverse.attach(observer);
}
void detach(scene::Traversable::Observer* observer)
{
m_traverse.detach(observer);
}
void attach( scene::Traversable::Observer* observer ){
m_traverse.attach( observer );
}
void detach( scene::Traversable::Observer* observer ){
m_traverse.detach( observer );
}
void renderSolid(Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld) const
{
renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly);
}
void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const {
renderer.SetState( m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly );
}
void renderWireframe(Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld, const AABB& childBounds) const
{
renderSolid(renderer, volume, localToWorld);
void renderWireframe( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld, const AABB& childBounds ) const {
renderSolid( renderer, volume, localToWorld );
if(g_showNames)
{
// don't draw the name for worldspawn
if(!strcmp(m_entity.getEntityClass().name(), "worldspawn"))
return;
if ( g_showNames ) {
// 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;
// place name in the middle of the "children cloud"
m_name_origin = childBounds.origin;
renderer.addRenderable(m_renderName, localToWorld);
}
}
renderer.addRenderable( m_renderName, localToWorld );
}
}
void updateTransform()
{
m_transform.localToParent() = g_matrix4_identity;
matrix4_translate_by_vec3(m_transform.localToParent(), m_origin);
m_transformChanged();
}
typedef MemberCaller<Group, &Group::updateTransform> UpdateTransformCaller;
void originChanged()
{
m_origin = m_originKey.m_origin;
updateTransform();
}
typedef MemberCaller<Group, &Group::originChanged> OriginChangedCaller;
void updateTransform(){
m_transform.localToParent() = g_matrix4_identity;
matrix4_translate_by_vec3( m_transform.localToParent(), m_origin );
m_transformChanged();
}
typedef MemberCaller<Group, &Group::updateTransform> UpdateTransformCaller;
void originChanged(){
m_origin = m_originKey.m_origin;
updateTransform();
}
typedef MemberCaller<Group, &Group::originChanged> OriginChangedCaller;
void translate(const Vector3& translation)
{
m_origin = origin_translated(m_origin, translation);
}
void translate( const Vector3& translation ){
m_origin = origin_translated( m_origin, translation );
}
void revertTransform()
{
m_origin = m_originKey.m_origin;
}
void freezeTransform()
{
m_originKey.m_origin = m_origin;
m_originKey.write(&m_entity);
}
void transformChanged()
{
revertTransform();
m_evaluateTransform();
updateTransform();
}
typedef MemberCaller<Group, &Group::transformChanged> TransformChangedCaller;
void revertTransform(){
m_origin = m_originKey.m_origin;
}
void freezeTransform(){
m_originKey.m_origin = m_origin;
m_originKey.write( &m_entity );
}
void transformChanged(){
revertTransform();
m_evaluateTransform();
updateTransform();
}
typedef MemberCaller<Group, &Group::transformChanged> TransformChangedCaller;
};
#if 0
class TransformableSetTranslation
{
Translation m_value;
Translation m_value;
public:
TransformableSetTranslation(const Translation& value) : m_value(value)
{
}
void operator()(Transformable& transformable) const
{
transformable.setTranslation(m_value);
}
TransformableSetTranslation( const Translation& value ) : m_value( value ){
}
void operator()( Transformable& transformable ) const {
transformable.setTranslation( m_value );
}
};
class TransformableSetRotation
{
Rotation m_value;
Rotation m_value;
public:
TransformableSetRotation(const Rotation& value) : m_value(value)
{
}
void operator()(Transformable& transformable) const
{
transformable.setRotation(m_value);
}
TransformableSetRotation( const Rotation& value ) : m_value( value ){
}
void operator()( Transformable& transformable ) const {
transformable.setRotation( m_value );
}
};
class TransformableSetScale
{
Scale m_value;
Scale m_value;
public:
TransformableSetScale(const Scale& value) : m_value(value)
{
}
void operator()(Transformable& transformable) const
{
transformable.setScale(m_value);
}
TransformableSetScale( const Scale& value ) : m_value( value ){
}
void operator()( Transformable& transformable ) const {
transformable.setScale( m_value );
}
};
class TransformableSetType
{
TransformModifierType m_value;
TransformModifierType m_value;
public:
TransformableSetType(const TransformModifierType& value) : m_value(value)
{
}
void operator()(Transformable& transformable) const
{
transformable.setType(m_value);
}
TransformableSetType( const TransformModifierType& value ) : m_value( value ){
}
void operator()( Transformable& transformable ) const {
transformable.setType( m_value );
}
};
class TransformableFreezeTransform
{
TransformModifierType m_value;
TransformModifierType m_value;
public:
void operator()(Transformable& transformable) const
{
transformable.freezeTransform();
}
void operator()( Transformable& transformable ) const {
transformable.freezeTransform();
}
};
template<typename Functor>
inline void Scene_forEachChildTransformable(const Functor& functor, const scene::Path& path)
{
GlobalSceneGraph().traverse_subgraph(ChildInstanceWalker< InstanceApply<Transformable, Functor> >(functor), path);
inline void Scene_forEachChildTransformable( const Functor& functor, const scene::Path& path ){
GlobalSceneGraph().traverse_subgraph( ChildInstanceWalker< InstanceApply<Transformable, Functor> >( functor ), path );
}
#endif
class GroupInstance :
public TargetableInstance,
public TransformModifier,
public TargetableInstance,
public TransformModifier,
#if 0
public Transformable,
public Transformable,
#endif
public Renderable
public Renderable
{
class TypeCasts
{
InstanceTypeCastTable m_casts;
public:
TypeCasts()
{
m_casts = TargetableInstance::StaticTypeCasts::instance().get();
InstanceStaticCast<GroupInstance, Renderable>::install(m_casts);
#if 0
InstanceStaticCast<GroupInstance, Transformable>::install(m_casts);
#endif
}
InstanceTypeCastTable& get()
{
return m_casts;
}
};
Group& m_contained;
class TypeCasts
{
InstanceTypeCastTable m_casts;
public:
typedef LazyStatic<TypeCasts> StaticTypeCasts;
TypeCasts(){
m_casts = TargetableInstance::StaticTypeCasts::instance().get();
InstanceStaticCast<GroupInstance, Renderable>::install( m_casts );
#if 0
InstanceStaticCast<GroupInstance, Transformable>::install( m_casts );
#endif
}
InstanceTypeCastTable& get(){
return m_casts;
}
};
GroupInstance(const scene::Path& path, scene::Instance* parent, Group& group) :
TargetableInstance(path, parent, this, StaticTypeCasts::instance().get(), group.getEntity(), *this),
TransformModifier(Group::TransformChangedCaller(group), ApplyTransformCaller(*this)),
m_contained(group)
{
m_contained.instanceAttach(Instance::path());
StaticRenderableConnectionLines::instance().attach(*this);
}
~GroupInstance()
{
StaticRenderableConnectionLines::instance().detach(*this);
m_contained.instanceDetach(Instance::path());
}
void renderSolid(Renderer& renderer, const VolumeTest& volume) const
{
m_contained.renderSolid(renderer, volume, Instance::localToWorld());
}
void renderWireframe(Renderer& renderer, const VolumeTest& volume) const
{
m_contained.renderWireframe(renderer, volume, Instance::localToWorld(), Instance::childBounds());
}
Group& m_contained;
public:
typedef LazyStatic<TypeCasts> StaticTypeCasts;
STRING_CONSTANT(Name, "GroupInstance");
GroupInstance( const scene::Path& path, scene::Instance* parent, Group& group ) :
TargetableInstance( path, parent, this, StaticTypeCasts::instance().get(), group.getEntity(), *this ),
TransformModifier( Group::TransformChangedCaller( group ), ApplyTransformCaller( *this ) ),
m_contained( group ){
m_contained.instanceAttach( Instance::path() );
StaticRenderableConnectionLines::instance().attach( *this );
}
~GroupInstance(){
StaticRenderableConnectionLines::instance().detach( *this );
m_contained.instanceDetach( Instance::path() );
}
void renderSolid( Renderer& renderer, const VolumeTest& volume ) const {
m_contained.renderSolid( renderer, volume, Instance::localToWorld() );
}
void renderWireframe( Renderer& renderer, const VolumeTest& volume ) const {
m_contained.renderWireframe( renderer, volume, Instance::localToWorld(), Instance::childBounds() );
}
STRING_CONSTANT( Name, "GroupInstance" );
#if 0
void setType(TransformModifierType type)
{
Scene_forEachChildTransformable(TransformableSetType(type), Instance::path());
}
void setTranslation(const Translation& value)
{
Scene_forEachChildTransformable(TransformableSetTranslation(value), Instance::path());
}
void setRotation(const Rotation& value)
{
Scene_forEachChildTransformable(TransformableSetRotation(value), Instance::path());
}
void setScale(const Scale& value)
{
Scene_forEachChildTransformable(TransformableSetScale(value), Instance::path());
}
void freezeTransform()
{
Scene_forEachChildTransformable(TransformableFreezeTransform(), Instance::path());
}
void setType( TransformModifierType type ){
Scene_forEachChildTransformable( TransformableSetType( type ), Instance::path() );
}
void setTranslation( const Translation& value ){
Scene_forEachChildTransformable( TransformableSetTranslation( value ), Instance::path() );
}
void setRotation( const Rotation& value ){
Scene_forEachChildTransformable( TransformableSetRotation( value ), Instance::path() );
}
void setScale( const Scale& value ){
Scene_forEachChildTransformable( TransformableSetScale( value ), Instance::path() );
}
void freezeTransform(){
Scene_forEachChildTransformable( TransformableFreezeTransform(), Instance::path() );
}
void evaluateTransform()
{
}
void evaluateTransform(){
}
#endif
void evaluateTransform()
{
if(getType() == TRANSFORM_PRIMITIVE)
{
m_contained.translate(getTranslation());
}
}
void applyTransform()
{
m_contained.revertTransform();
evaluateTransform();
m_contained.freezeTransform();
}
typedef MemberCaller<GroupInstance, &GroupInstance::applyTransform> ApplyTransformCaller;
void evaluateTransform(){
if ( getType() == TRANSFORM_PRIMITIVE ) {
m_contained.translate( getTranslation() );
}
}
void applyTransform(){
m_contained.revertTransform();
evaluateTransform();
m_contained.freezeTransform();
}
typedef MemberCaller<GroupInstance, &GroupInstance::applyTransform> ApplyTransformCaller;
};
class GroupNode :
public scene::Node::Symbiot,
public scene::Instantiable,
public scene::Cloneable,
public scene::Traversable::Observer
public scene::Node::Symbiot,
public scene::Instantiable,
public scene::Cloneable,
public scene::Traversable::Observer
{
class TypeCasts
{
NodeTypeCastTable m_casts;
public:
TypeCasts()
{
NodeStaticCast<GroupNode, scene::Instantiable>::install(m_casts);
NodeStaticCast<GroupNode, scene::Cloneable>::install(m_casts);
NodeContainedCast<GroupNode, scene::Traversable>::install(m_casts);
NodeContainedCast<GroupNode, TransformNode>::install(m_casts);
NodeContainedCast<GroupNode, Entity>::install(m_casts);
NodeContainedCast<GroupNode, Nameable>::install(m_casts);
NodeContainedCast<GroupNode, Namespaced>::install(m_casts);
}
NodeTypeCastTable& get()
{
return m_casts;
}
};
class TypeCasts
{
NodeTypeCastTable m_casts;
public:
TypeCasts(){
NodeStaticCast<GroupNode, scene::Instantiable>::install( m_casts );
NodeStaticCast<GroupNode, scene::Cloneable>::install( m_casts );
NodeContainedCast<GroupNode, scene::Traversable>::install( m_casts );
NodeContainedCast<GroupNode, TransformNode>::install( m_casts );
NodeContainedCast<GroupNode, Entity>::install( m_casts );
NodeContainedCast<GroupNode, Nameable>::install( m_casts );
NodeContainedCast<GroupNode, Namespaced>::install( m_casts );
}
NodeTypeCastTable& get(){
return m_casts;
}
};
scene::Node m_node;
InstanceSet m_instances;
Group m_contained;
scene::Node m_node;
InstanceSet m_instances;
Group m_contained;
void construct()
{
m_contained.attach(this);
}
void destroy()
{
m_contained.detach(this);
}
void construct(){
m_contained.attach( this );
}
void destroy(){
m_contained.detach( this );
}
public:
typedef LazyStatic<TypeCasts> StaticTypeCasts;
typedef LazyStatic<TypeCasts> StaticTypeCasts;
scene::Traversable& get(NullType<scene::Traversable>)
{
return m_contained.getTraversable();
}
TransformNode& get(NullType<TransformNode>)
{
return m_contained.getTransformNode();
}
Entity& get(NullType<Entity>)
{
return m_contained.getEntity();
}
Nameable& get(NullType<Nameable>)
{
return m_contained.getNameable();
}
Namespaced& get(NullType<Namespaced>)
{
return m_contained.getNamespaced();
}
scene::Traversable& get( NullType<scene::Traversable>){
return m_contained.getTraversable();
}
TransformNode& get( NullType<TransformNode>){
return m_contained.getTransformNode();
}
Entity& get( NullType<Entity>){
return m_contained.getEntity();
}
Nameable& get( NullType<Nameable>){
return m_contained.getNameable();
}
Namespaced& get( NullType<Namespaced>){
return m_contained.getNamespaced();
}
GroupNode(EntityClass* eclass) :
m_node(this, this, StaticTypeCasts::instance().get()),
m_contained(eclass, m_node, InstanceSet::TransformChangedCaller(m_instances), InstanceSetEvaluateTransform<GroupInstance>::Caller(m_instances))
{
construct();
}
GroupNode(const GroupNode& 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), InstanceSetEvaluateTransform<GroupInstance>::Caller(m_instances))
{
construct();
}
~GroupNode()
{
destroy();
}
GroupNode( EntityClass* eclass ) :
m_node( this, this, StaticTypeCasts::instance().get() ),
m_contained( eclass, m_node, InstanceSet::TransformChangedCaller( m_instances ), InstanceSetEvaluateTransform<GroupInstance>::Caller( m_instances ) ){
construct();
}
GroupNode( const GroupNode& 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 ), InstanceSetEvaluateTransform<GroupInstance>::Caller( m_instances ) ){
construct();
}
~GroupNode(){
destroy();
}
void release()
{
delete this;
}
scene::Node& node()
{
return m_node;
}
void release(){
delete this;
}
scene::Node& node(){
return m_node;
}
scene::Node& clone() const
{
return (new GroupNode(*this))->node();
}
scene::Node& clone() const {
return ( new GroupNode( *this ) )->node();
}
void insert(scene::Node& child)
{
m_instances.insert(child);
}
void erase(scene::Node& child)
{
m_instances.erase(child);
}
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 GroupInstance(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);
}
scene::Instance* create( const scene::Path& path, scene::Instance* parent ){
return new GroupInstance( 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 );
}
};
scene::Node& New_Group(EntityClass* eclass)
{
return (new GroupNode(eclass))->node();
scene::Node& New_Group( EntityClass* eclass ){
return ( new GroupNode( eclass ) )->node();
}

View File

@@ -1,27 +1,27 @@
/*
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
*/
#if !defined(INCLUDED_GROUP_H)
#if !defined( INCLUDED_GROUP_H )
#define INCLUDED_GROUP_H
scene::Node& New_Group(EntityClass* eclass);
scene::Node& New_Group( EntityClass* eclass );
#endif

View File

@@ -1,23 +1,22 @@
/*
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
*/
#include "keyobservers.h"

View File

@@ -1,25 +1,25 @@
/*
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
*/
#if !defined(INCLUDED_KEYOBSERVERS_H)
#if !defined( INCLUDED_KEYOBSERVERS_H )
#define INCLUDED_KEYOBSERVERS_H
#include "entitylib.h"
@@ -27,27 +27,24 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
class KeyObserverMap : public Entity::Observer
{
typedef std::multimap<const char*, KeyObserver, RawStringLess> KeyObservers;
KeyObservers m_keyObservers;
typedef std::multimap<const char*, KeyObserver, RawStringLess> KeyObservers;
KeyObservers m_keyObservers;
public:
void insert(const char* key, const KeyObserver& observer)
{
m_keyObservers.insert(KeyObservers::value_type(key, observer));
}
void insert(const char* key, EntityKeyValue& value)
{
for(KeyObservers::const_iterator i = m_keyObservers.find(key); i != m_keyObservers.end() && string_equal((*i).first, key); ++i)
{
value.attach((*i).second);
}
}
void erase(const char* key, EntityKeyValue& value)
{
for(KeyObservers::const_iterator i = m_keyObservers.find(key); i != m_keyObservers.end() && string_equal((*i).first, key); ++i)
{
value.detach((*i).second);
}
}
void insert( const char* key, const KeyObserver& observer ){
m_keyObservers.insert( KeyObservers::value_type( key, observer ) );
}
void insert( const char* key, EntityKeyValue& value ){
for ( KeyObservers::const_iterator i = m_keyObservers.find( key ); i != m_keyObservers.end() && string_equal( ( *i ).first, key ); ++i )
{
value.attach( ( *i ).second );
}
}
void erase( const char* key, EntityKeyValue& value ){
for ( KeyObservers::const_iterator i = m_keyObservers.find( key ); i != m_keyObservers.end() && string_equal( ( *i ).first, key ); ++i )
{
value.detach( ( *i ).second );
}
}
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,41 +1,41 @@
/*
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
*/
#if !defined(INCLUDED_LIGHT_H)
#if !defined( INCLUDED_LIGHT_H )
#define INCLUDED_LIGHT_H
namespace scene
{
class Node;
class Node;
};
class EntityClass;
scene::Node& New_Light(EntityClass* eclass);
scene::Node& New_Light( EntityClass* eclass );
enum LightType
{
LIGHTTYPE_DEFAULT,
LIGHTTYPE_RTCW,
LIGHTTYPE_DOOM3
LIGHTTYPE_DEFAULT,
LIGHTTYPE_RTCW,
LIGHTTYPE_DOOM3
};
void Light_Construct(LightType lightType);
void Light_Construct( LightType lightType );
void Light_Destroy();
#endif

View File

@@ -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 the Quake3 misc_model entity.
@@ -51,426 +51,362 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "entity.h"
class MiscModel :
public Snappable
public Snappable
{
EntityKeyValues m_entity;
KeyObserverMap m_keyObservers;
MatrixTransform m_transform;
EntityKeyValues m_entity;
KeyObserverMap m_keyObservers;
MatrixTransform m_transform;
OriginKey m_originKey;
Vector3 m_origin;
AnglesKey m_anglesKey;
Vector3 m_angles;
ScaleKey m_scaleKey;
Vector3 m_scale;
OriginKey m_originKey;
Vector3 m_origin;
AnglesKey m_anglesKey;
Vector3 m_angles;
ScaleKey m_scaleKey;
Vector3 m_scale;
SingletonModel m_model;
SingletonModel m_model;
ClassnameFilter m_filter;
NamedEntity m_named;
NameKeys m_nameKeys;
RenderablePivot m_renderOrigin;
RenderableNamedEntity m_renderName;
ClassnameFilter m_filter;
NamedEntity m_named;
NameKeys m_nameKeys;
RenderablePivot m_renderOrigin;
RenderableNamedEntity m_renderName;
Callback m_transformChanged;
Callback m_evaluateTransform;
Callback m_transformChanged;
Callback m_evaluateTransform;
void construct()
{
m_keyObservers.insert("classname", ClassnameFilter::ClassnameChangedCaller(m_filter));
m_keyObservers.insert(Static<KeyIsName>::instance().m_nameKey, NamedEntity::IdentifierChangedCaller(m_named));
m_keyObservers.insert("model", SingletonModel::ModelChangedCaller(m_model));
m_keyObservers.insert("origin", OriginKey::OriginChangedCaller(m_originKey));
m_keyObservers.insert("angle", AnglesKey::AngleChangedCaller(m_anglesKey));
m_keyObservers.insert("angles", AnglesKey::AnglesChangedCaller(m_anglesKey));
m_keyObservers.insert("modelscale", ScaleKey::UniformScaleChangedCaller(m_scaleKey));
m_keyObservers.insert("modelscale_vec", ScaleKey::ScaleChangedCaller(m_scaleKey));
}
void construct(){
m_keyObservers.insert( "classname", ClassnameFilter::ClassnameChangedCaller( m_filter ) );
m_keyObservers.insert( Static<KeyIsName>::instance().m_nameKey, NamedEntity::IdentifierChangedCaller( m_named ) );
m_keyObservers.insert( "model", SingletonModel::ModelChangedCaller( m_model ) );
m_keyObservers.insert( "origin", OriginKey::OriginChangedCaller( m_originKey ) );
m_keyObservers.insert( "angle", AnglesKey::AngleChangedCaller( m_anglesKey ) );
m_keyObservers.insert( "angles", AnglesKey::AnglesChangedCaller( m_anglesKey ) );
m_keyObservers.insert( "modelscale", ScaleKey::UniformScaleChangedCaller( m_scaleKey ) );
m_keyObservers.insert( "modelscale_vec", ScaleKey::ScaleChangedCaller( m_scaleKey ) );
}
void updateTransform()
{
m_transform.localToParent() = g_matrix4_identity;
matrix4_transform_by_euler_xyz_degrees(m_transform.localToParent(), m_origin, m_angles, m_scale);
m_transformChanged();
}
void updateTransform(){
m_transform.localToParent() = g_matrix4_identity;
matrix4_transform_by_euler_xyz_degrees( m_transform.localToParent(), m_origin, m_angles, m_scale );
m_transformChanged();
}
// vc 2k5 compiler fix
// vc 2k5 compiler fix
#if _MSC_VER >= 1400
public:
#endif
void originChanged()
{
m_origin = m_originKey.m_origin;
updateTransform();
}
typedef MemberCaller<MiscModel, &MiscModel::originChanged> OriginChangedCaller;
void anglesChanged()
{
m_angles = m_anglesKey.m_angles;
updateTransform();
}
typedef MemberCaller<MiscModel, &MiscModel::anglesChanged> AnglesChangedCaller;
void scaleChanged()
{
m_scale = m_scaleKey.m_scale;
updateTransform();
}
typedef MemberCaller<MiscModel, &MiscModel::scaleChanged> ScaleChangedCaller;
public:
#endif
void originChanged(){
m_origin = m_originKey.m_origin;
updateTransform();
}
typedef MemberCaller<MiscModel, &MiscModel::originChanged> OriginChangedCaller;
void anglesChanged(){
m_angles = m_anglesKey.m_angles;
updateTransform();
}
typedef MemberCaller<MiscModel, &MiscModel::anglesChanged> AnglesChangedCaller;
void scaleChanged(){
m_scale = m_scaleKey.m_scale;
updateTransform();
}
typedef MemberCaller<MiscModel, &MiscModel::scaleChanged> ScaleChangedCaller;
public:
MiscModel(EntityClass* eclass, scene::Node& node, const Callback& transformChanged, const Callback& evaluateTransform) :
m_entity(eclass),
m_originKey(OriginChangedCaller(*this)),
m_origin(ORIGINKEY_IDENTITY),
m_anglesKey(AnglesChangedCaller(*this)),
m_angles(ANGLESKEY_IDENTITY),
m_scaleKey(ScaleChangedCaller(*this)),
m_scale(SCALEKEY_IDENTITY),
m_filter(m_entity, node),
m_named(m_entity),
m_nameKeys(m_entity),
m_renderName(m_named, g_vector3_identity),
m_transformChanged(transformChanged),
m_evaluateTransform(evaluateTransform)
{
construct();
}
MiscModel(const MiscModel& other, scene::Node& node, const Callback& transformChanged, const Callback& evaluateTransform) :
m_entity(other.m_entity),
m_originKey(OriginChangedCaller(*this)),
m_origin(ORIGINKEY_IDENTITY),
m_anglesKey(AnglesChangedCaller(*this)),
m_angles(ANGLESKEY_IDENTITY),
m_scaleKey(ScaleChangedCaller(*this)),
m_scale(SCALEKEY_IDENTITY),
m_filter(m_entity, node),
m_named(m_entity),
m_nameKeys(m_entity),
m_renderName(m_named, g_vector3_identity),
m_transformChanged(transformChanged),
m_evaluateTransform(evaluateTransform)
{
construct();
}
MiscModel( EntityClass* eclass, scene::Node& node, const Callback& transformChanged, const Callback& evaluateTransform ) :
m_entity( eclass ),
m_originKey( OriginChangedCaller( *this ) ),
m_origin( ORIGINKEY_IDENTITY ),
m_anglesKey( AnglesChangedCaller( *this ) ),
m_angles( ANGLESKEY_IDENTITY ),
m_scaleKey( ScaleChangedCaller( *this ) ),
m_scale( SCALEKEY_IDENTITY ),
m_filter( m_entity, node ),
m_named( m_entity ),
m_nameKeys( m_entity ),
m_renderName( m_named, g_vector3_identity ),
m_transformChanged( transformChanged ),
m_evaluateTransform( evaluateTransform ){
construct();
}
MiscModel( const MiscModel& other, scene::Node& node, const Callback& transformChanged, const Callback& evaluateTransform ) :
m_entity( other.m_entity ),
m_originKey( OriginChangedCaller( *this ) ),
m_origin( ORIGINKEY_IDENTITY ),
m_anglesKey( AnglesChangedCaller( *this ) ),
m_angles( ANGLESKEY_IDENTITY ),
m_scaleKey( ScaleChangedCaller( *this ) ),
m_scale( SCALEKEY_IDENTITY ),
m_filter( m_entity, node ),
m_named( m_entity ),
m_nameKeys( m_entity ),
m_renderName( m_named, g_vector3_identity ),
m_transformChanged( transformChanged ),
m_evaluateTransform( evaluateTransform ){
construct();
}
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_entity.attach(m_keyObservers);
}
}
void instanceDetach(const scene::Path& path)
{
if(--m_instanceCounter.m_count == 0)
{
m_entity.detach(m_keyObservers);
m_entity.instanceDetach(path_find_mapfile(path.begin(), path.end()));
m_filter.instanceDetach();
}
}
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_entity.attach( m_keyObservers );
}
}
void instanceDetach( const scene::Path& path ){
if ( --m_instanceCounter.m_count == 0 ) {
m_entity.detach( m_keyObservers );
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;
}
EntityKeyValues& getEntity(){
return m_entity;
}
const EntityKeyValues& getEntity() const {
return m_entity;
}
scene::Traversable& getTraversable()
{
return m_model.getTraversable();
}
Namespaced& getNamespaced()
{
return m_nameKeys;
}
Nameable& getNameable()
{
return m_named;
}
TransformNode& getTransformNode()
{
return m_transform;
}
scene::Traversable& getTraversable(){
return m_model.getTraversable();
}
Namespaced& getNamespaced(){
return m_nameKeys;
}
Nameable& getNameable(){
return m_named;
}
TransformNode& getTransformNode(){
return m_transform;
}
void attach(scene::Traversable::Observer* observer)
{
m_model.attach(observer);
}
void detach(scene::Traversable::Observer* observer)
{
m_model.detach(observer);
}
void attach( scene::Traversable::Observer* observer ){
m_model.attach( observer );
}
void detach( scene::Traversable::Observer* observer ){
m_model.detach( observer );
}
void renderSolid(Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld, bool selected) const
{
if(selected)
{
m_renderOrigin.render(renderer, volume, localToWorld);
}
void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld, bool selected ) const {
if ( selected ) {
m_renderOrigin.render( renderer, volume, localToWorld );
}
renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly);
}
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);
}
}
renderer.SetState( m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly );
}
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 translate(const Vector3& translation)
{
m_origin = origin_translated(m_origin, translation);
}
void rotate(const Quaternion& rotation)
{
m_angles = angles_rotated(m_angles, rotation);
}
void scale(const Vector3& scaling)
{
m_scale = scale_scaled(m_scale, scaling);
}
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;
m_angles = m_anglesKey.m_angles;
m_scale = m_scaleKey.m_scale;
}
void freezeTransform()
{
m_originKey.m_origin = m_origin;
m_originKey.write(&m_entity);
m_anglesKey.m_angles = m_angles;
m_anglesKey.write(&m_entity);
m_scaleKey.m_scale = m_scale;
m_scaleKey.write(&m_entity);
}
void transformChanged()
{
revertTransform();
m_evaluateTransform();
updateTransform();
}
typedef MemberCaller<MiscModel, &MiscModel::transformChanged> TransformChangedCaller;
void translate( const Vector3& translation ){
m_origin = origin_translated( m_origin, translation );
}
void rotate( const Quaternion& rotation ){
m_angles = angles_rotated( m_angles, rotation );
}
void scale( const Vector3& scaling ){
m_scale = scale_scaled( m_scale, scaling );
}
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;
m_angles = m_anglesKey.m_angles;
m_scale = m_scaleKey.m_scale;
}
void freezeTransform(){
m_originKey.m_origin = m_origin;
m_originKey.write( &m_entity );
m_anglesKey.m_angles = m_angles;
m_anglesKey.write( &m_entity );
m_scaleKey.m_scale = m_scale;
m_scaleKey.write( &m_entity );
}
void transformChanged(){
revertTransform();
m_evaluateTransform();
updateTransform();
}
typedef MemberCaller<MiscModel, &MiscModel::transformChanged> TransformChangedCaller;
};
class MiscModelInstance : public TargetableInstance, public TransformModifier, public Renderable
{
class TypeCasts
{
InstanceTypeCastTable m_casts;
public:
TypeCasts()
{
m_casts = TargetableInstance::StaticTypeCasts::instance().get();
InstanceStaticCast<MiscModelInstance, Renderable>::install(m_casts);
InstanceStaticCast<MiscModelInstance, Transformable>::install(m_casts);
InstanceIdentityCast<MiscModelInstance>::install(m_casts);
}
InstanceTypeCastTable& get()
{
return m_casts;
}
};
MiscModel& m_contained;
class TypeCasts
{
InstanceTypeCastTable m_casts;
public:
typedef LazyStatic<TypeCasts> StaticTypeCasts;
TypeCasts(){
m_casts = TargetableInstance::StaticTypeCasts::instance().get();
InstanceStaticCast<MiscModelInstance, Renderable>::install( m_casts );
InstanceStaticCast<MiscModelInstance, Transformable>::install( m_casts );
InstanceIdentityCast<MiscModelInstance>::install( m_casts );
}
InstanceTypeCastTable& get(){
return m_casts;
}
};
STRING_CONSTANT(Name, "MiscModelInstance");
MiscModel& m_contained;
public:
typedef LazyStatic<TypeCasts> StaticTypeCasts;
MiscModelInstance(const scene::Path& path, scene::Instance* parent, MiscModel& miscmodel) :
TargetableInstance(path, parent, this, StaticTypeCasts::instance().get(), miscmodel.getEntity(), *this),
TransformModifier(MiscModel::TransformChangedCaller(miscmodel), ApplyTransformCaller(*this)),
m_contained(miscmodel)
{
m_contained.instanceAttach(Instance::path());
StaticRenderableConnectionLines::instance().attach(*this);
}
~MiscModelInstance()
{
StaticRenderableConnectionLines::instance().detach(*this);
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());
}
void evaluateTransform()
{
if(getType() == TRANSFORM_PRIMITIVE)
{
m_contained.translate(getTranslation());
m_contained.rotate(getRotation());
m_contained.scale(getScale());
}
}
void applyTransform()
{
m_contained.revertTransform();
evaluateTransform();
m_contained.freezeTransform();
}
typedef MemberCaller<MiscModelInstance, &MiscModelInstance::applyTransform> ApplyTransformCaller;
STRING_CONSTANT( Name, "MiscModelInstance" );
MiscModelInstance( const scene::Path& path, scene::Instance* parent, MiscModel& miscmodel ) :
TargetableInstance( path, parent, this, StaticTypeCasts::instance().get(), miscmodel.getEntity(), *this ),
TransformModifier( MiscModel::TransformChangedCaller( miscmodel ), ApplyTransformCaller( *this ) ),
m_contained( miscmodel ){
m_contained.instanceAttach( Instance::path() );
StaticRenderableConnectionLines::instance().attach( *this );
}
~MiscModelInstance(){
StaticRenderableConnectionLines::instance().detach( *this );
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() );
}
void evaluateTransform(){
if ( getType() == TRANSFORM_PRIMITIVE ) {
m_contained.translate( getTranslation() );
m_contained.rotate( getRotation() );
m_contained.scale( getScale() );
}
}
void applyTransform(){
m_contained.revertTransform();
evaluateTransform();
m_contained.freezeTransform();
}
typedef MemberCaller<MiscModelInstance, &MiscModelInstance::applyTransform> ApplyTransformCaller;
};
class MiscModelNode :
public scene::Node::Symbiot,
public scene::Instantiable,
public scene::Cloneable,
public scene::Traversable::Observer
public scene::Node::Symbiot,
public scene::Instantiable,
public scene::Cloneable,
public scene::Traversable::Observer
{
class TypeCasts
{
NodeTypeCastTable m_casts;
public:
TypeCasts()
{
NodeStaticCast<MiscModelNode, scene::Instantiable>::install(m_casts);
NodeStaticCast<MiscModelNode, scene::Cloneable>::install(m_casts);
NodeContainedCast<MiscModelNode, scene::Traversable>::install(m_casts);
NodeContainedCast<MiscModelNode, Snappable>::install(m_casts);
NodeContainedCast<MiscModelNode, TransformNode>::install(m_casts);
NodeContainedCast<MiscModelNode, Entity>::install(m_casts);
NodeContainedCast<MiscModelNode, Nameable>::install(m_casts);
NodeContainedCast<MiscModelNode, Namespaced>::install(m_casts);
}
NodeTypeCastTable& get()
{
return m_casts;
}
};
scene::Node m_node;
InstanceSet m_instances;
MiscModel m_contained;
void construct()
{
m_contained.attach(this);
}
void destroy()
{
m_contained.detach(this);
}
class TypeCasts
{
NodeTypeCastTable m_casts;
public:
typedef LazyStatic<TypeCasts> StaticTypeCasts;
scene::Traversable& get(NullType<scene::Traversable>)
{
return m_contained.getTraversable();
}
Snappable& get(NullType<Snappable>)
{
return m_contained;
}
TransformNode& get(NullType<TransformNode>)
{
return m_contained.getTransformNode();
}
Entity& get(NullType<Entity>)
{
return m_contained.getEntity();
}
Nameable& get(NullType<Nameable>)
{
return m_contained.getNameable();
}
Namespaced& get(NullType<Namespaced>)
{
return m_contained.getNamespaced();
}
MiscModelNode(EntityClass* eclass) :
m_node(this, this, StaticTypeCasts::instance().get()),
m_contained(eclass, m_node, InstanceSet::TransformChangedCaller(m_instances), InstanceSetEvaluateTransform<MiscModelInstance>::Caller(m_instances))
{
construct();
}
MiscModelNode(const MiscModelNode& 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), InstanceSetEvaluateTransform<MiscModelInstance>::Caller(m_instances))
{
construct();
}
~MiscModelNode()
{
destroy();
}
void release()
{
delete this;
}
scene::Node& node()
{
return m_node;
}
scene::Node& clone() const
{
return (new MiscModelNode(*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 MiscModelInstance(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);
}
TypeCasts(){
NodeStaticCast<MiscModelNode, scene::Instantiable>::install( m_casts );
NodeStaticCast<MiscModelNode, scene::Cloneable>::install( m_casts );
NodeContainedCast<MiscModelNode, scene::Traversable>::install( m_casts );
NodeContainedCast<MiscModelNode, Snappable>::install( m_casts );
NodeContainedCast<MiscModelNode, TransformNode>::install( m_casts );
NodeContainedCast<MiscModelNode, Entity>::install( m_casts );
NodeContainedCast<MiscModelNode, Nameable>::install( m_casts );
NodeContainedCast<MiscModelNode, Namespaced>::install( m_casts );
}
NodeTypeCastTable& get(){
return m_casts;
}
};
scene::Node& New_MiscModel(EntityClass* eclass)
{
return (new MiscModelNode(eclass))->node();
scene::Node m_node;
InstanceSet m_instances;
MiscModel m_contained;
void construct(){
m_contained.attach( this );
}
void destroy(){
m_contained.detach( this );
}
void MiscModel_construct()
{
public:
typedef LazyStatic<TypeCasts> StaticTypeCasts;
scene::Traversable& get( NullType<scene::Traversable>){
return m_contained.getTraversable();
}
void MiscModel_destroy()
{
Snappable& get( NullType<Snappable>){
return m_contained;
}
TransformNode& get( NullType<TransformNode>){
return m_contained.getTransformNode();
}
Entity& get( NullType<Entity>){
return m_contained.getEntity();
}
Nameable& get( NullType<Nameable>){
return m_contained.getNameable();
}
Namespaced& get( NullType<Namespaced>){
return m_contained.getNamespaced();
}
MiscModelNode( EntityClass* eclass ) :
m_node( this, this, StaticTypeCasts::instance().get() ),
m_contained( eclass, m_node, InstanceSet::TransformChangedCaller( m_instances ), InstanceSetEvaluateTransform<MiscModelInstance>::Caller( m_instances ) ){
construct();
}
MiscModelNode( const MiscModelNode& 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 ), InstanceSetEvaluateTransform<MiscModelInstance>::Caller( m_instances ) ){
construct();
}
~MiscModelNode(){
destroy();
}
void release(){
delete this;
}
scene::Node& node(){
return m_node;
}
scene::Node& clone() const {
return ( new MiscModelNode( *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 MiscModelInstance( 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 );
}
};
scene::Node& New_MiscModel( EntityClass* eclass ){
return ( new MiscModelNode( eclass ) )->node();
}
void MiscModel_construct(){
}
void MiscModel_destroy(){
}

View File

@@ -1,28 +1,28 @@
/*
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
*/
#if !defined(INCLUDED_MISCMODEL_H)
#if !defined( INCLUDED_MISCMODEL_H )
#define INCLUDED_MISCMODEL_H
scene::Node& New_MiscModel(EntityClass* eclass);
scene::Node& New_MiscModel( EntityClass* eclass );
void MiscModel_construct();
void MiscModel_destroy();

View File

@@ -1,23 +1,22 @@
/*
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
*/
#include "model.h"

View File

@@ -1,25 +1,25 @@
/*
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
*/
#if !defined(INCLUDED_MODEL_H)
#if !defined( INCLUDED_MODEL_H )
#define INCLUDED_MODEL_H
#include "entitylib.h"
@@ -31,94 +31,79 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
class EModel : public ModuleObserver
{
ResourceReference m_resource;
scene::Traversable& m_traverse;
scene::Node* m_node;
Callback m_modelChanged;
ResourceReference m_resource;
scene::Traversable& m_traverse;
scene::Node* m_node;
Callback m_modelChanged;
public:
EModel(scene::Traversable& traversable, const Callback& modelChanged)
: m_resource(""), m_traverse(traversable), m_node(0), m_modelChanged(modelChanged)
{
m_resource.attach(*this);
}
~EModel()
{
m_resource.detach(*this);
}
EModel( scene::Traversable& traversable, const Callback& modelChanged )
: m_resource( "" ), m_traverse( traversable ), m_node( 0 ), m_modelChanged( modelChanged ){
m_resource.attach( *this );
}
~EModel(){
m_resource.detach( *this );
}
void realise()
{
m_resource.get()->load();
m_node = m_resource.get()->getNode();
if(m_node != 0)
{
m_traverse.insert(*m_node);
}
}
void unrealise()
{
if(m_node != 0)
{
m_traverse.erase(*m_node);
}
}
void modelChanged(const char* value)
{
StringOutputStream cleaned(string_length(value));
cleaned << PathCleaned(value);
m_resource.detach(*this);
m_resource.setName(cleaned.c_str());
m_resource.attach(*this);
m_modelChanged();
}
typedef MemberCaller1<EModel, const char*, &EModel::modelChanged> ModelChangedCaller;
void realise(){
m_resource.get()->load();
m_node = m_resource.get()->getNode();
if ( m_node != 0 ) {
m_traverse.insert( *m_node );
}
}
void unrealise(){
if ( m_node != 0 ) {
m_traverse.erase( *m_node );
}
}
const char* getName() const
{
return m_resource.getName();
}
scene::Node* getNode() const
{
return m_node;
}
void modelChanged( const char* value ){
StringOutputStream cleaned( string_length( value ) );
cleaned << PathCleaned( value );
m_resource.detach( *this );
m_resource.setName( cleaned.c_str() );
m_resource.attach( *this );
m_modelChanged();
}
typedef MemberCaller1<EModel, const char*, &EModel::modelChanged> ModelChangedCaller;
const char* getName() const {
return m_resource.getName();
}
scene::Node* getNode() const {
return m_node;
}
};
class SingletonModel
{
TraversableNode m_traverse;
EModel m_model;
TraversableNode m_traverse;
EModel m_model;
public:
SingletonModel()
: m_model(m_traverse, Callback())
{
}
SingletonModel()
: m_model( m_traverse, Callback() ){
}
void attach(scene::Traversable::Observer* observer)
{
m_traverse.attach(observer);
}
void detach(scene::Traversable::Observer* observer)
{
m_traverse.detach(observer);
}
void attach( scene::Traversable::Observer* observer ){
m_traverse.attach( observer );
}
void detach( scene::Traversable::Observer* observer ){
m_traverse.detach( observer );
}
scene::Traversable& getTraversable()
{
return m_traverse;
}
scene::Traversable& getTraversable(){
return m_traverse;
}
void modelChanged(const char* value)
{
m_model.modelChanged(value);
}
typedef MemberCaller1<SingletonModel, const char*, &SingletonModel::modelChanged> ModelChangedCaller;
void modelChanged( const char* value ){
m_model.modelChanged( value );
}
typedef MemberCaller1<SingletonModel, const char*, &SingletonModel::modelChanged> ModelChangedCaller;
scene::Node* getNode() const
{
return m_model.getNode();
}
scene::Node* getNode() const {
return m_model.getNode();
}
};
#endif

View File

@@ -1,23 +1,22 @@
/*
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
*/
#include "modelskinkey.h"

View File

@@ -1,25 +1,25 @@
/*
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
*/
#if !defined(INCLUDED_MODELSKINKEY_H)
#if !defined( INCLUDED_MODELSKINKEY_H )
#define INCLUDED_MODELSKINKEY_H
#include "modelskin.h"
@@ -30,82 +30,70 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "entitylib.h"
#include "traverselib.h"
inline void parseTextureName(CopiedString& name, const char* token)
{
StringOutputStream cleaned(256);
cleaned << PathCleaned(token);
name = StringRange(cleaned.c_str(), path_get_filename_base_end(cleaned.c_str())); // remove extension
inline void parseTextureName( CopiedString& name, const char* token ){
StringOutputStream cleaned( 256 );
cleaned << PathCleaned( token );
name = StringRange( cleaned.c_str(), path_get_filename_base_end( cleaned.c_str() ) ); // remove extension
}
class ModelSkinKey : public ModuleObserver
{
CopiedString m_name;
ModelSkin* m_skin;
Callback m_skinChangedCallback;
CopiedString m_name;
ModelSkin* m_skin;
Callback m_skinChangedCallback;
ModelSkinKey(const ModelSkinKey&);
ModelSkinKey operator=(const ModelSkinKey&);
ModelSkinKey( const ModelSkinKey& );
ModelSkinKey operator=( const ModelSkinKey& );
void construct()
{
m_skin = &GlobalModelSkinCache().capture(m_name.c_str());
m_skin->attach(*this);
}
void destroy()
{
m_skin->detach(*this);
GlobalModelSkinCache().release(m_name.c_str());
}
void construct(){
m_skin = &GlobalModelSkinCache().capture( m_name.c_str() );
m_skin->attach( *this );
}
void destroy(){
m_skin->detach( *this );
GlobalModelSkinCache().release( m_name.c_str() );
}
public:
ModelSkinKey(const Callback& skinChangedCallback) : m_skinChangedCallback(skinChangedCallback)
{
construct();
}
~ModelSkinKey()
{
destroy();
}
ModelSkin& get() const
{
return *m_skin;
}
void skinChanged(const char* value)
{
destroy();
parseTextureName(m_name, value);
construct();
}
typedef MemberCaller1<ModelSkinKey, const char*, &ModelSkinKey::skinChanged> SkinChangedCaller;
ModelSkinKey( const Callback& skinChangedCallback ) : m_skinChangedCallback( skinChangedCallback ){
construct();
}
~ModelSkinKey(){
destroy();
}
ModelSkin& get() const {
return *m_skin;
}
void skinChanged( const char* value ){
destroy();
parseTextureName( m_name, value );
construct();
}
typedef MemberCaller1<ModelSkinKey, const char*, &ModelSkinKey::skinChanged> SkinChangedCaller;
void realise()
{
m_skinChangedCallback();
}
void unrealise()
{
}
void realise(){
m_skinChangedCallback();
}
void unrealise(){
}
};
class InstanceSkinChanged : public scene::Instantiable::Visitor
{
public:
void visit(scene::Instance& instance) const
{
//\todo don't do this for instances that are not children of the entity setting the skin
SkinnedModel* skinned = InstanceTypeCast<SkinnedModel>::cast(instance);
if(skinned != 0)
{
skinned->skinChanged();
}
}
void visit( scene::Instance& instance ) const {
//\todo don't do this for instances that are not children of the entity setting the skin
SkinnedModel* skinned = InstanceTypeCast<SkinnedModel>::cast( instance );
if ( skinned != 0 ) {
skinned->skinChanged();
}
}
};
inline void Node_modelSkinChanged(scene::Node& node)
{
scene::Instantiable* instantiable = Node_getInstantiable(node);
ASSERT_NOTNULL(instantiable);
instantiable->forEachInstance(InstanceSkinChanged());
inline void Node_modelSkinChanged( scene::Node& node ){
scene::Instantiable* instantiable = Node_getInstantiable( node );
ASSERT_NOTNULL( instantiable );
instantiable->forEachInstance( InstanceSkinChanged() );
}
#endif

View File

@@ -1,23 +1,22 @@
/*
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
*/
#include "namedentity.h"

View File

@@ -1,25 +1,25 @@
/*
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
*/
#if !defined(INCLUDED_NAMEDENTITY_H)
#if !defined( INCLUDED_NAMEDENTITY_H )
#define INCLUDED_NAMEDENTITY_H
#include "entitylib.h"
@@ -31,81 +31,69 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
class NameCallbackSet
{
typedef std::set<NameCallback> NameCallbacks;
NameCallbacks m_callbacks;
typedef std::set<NameCallback> NameCallbacks;
NameCallbacks m_callbacks;
public:
void insert(const NameCallback& callback)
{
m_callbacks.insert(callback);
}
void erase(const NameCallback& callback)
{
m_callbacks.erase(callback);
}
void changed(const char* name) const
{
for(NameCallbacks::const_iterator i = m_callbacks.begin(); i != m_callbacks.end(); ++i)
{
(*i)(name);
}
}
void insert( const NameCallback& callback ){
m_callbacks.insert( callback );
}
void erase( const NameCallback& callback ){
m_callbacks.erase( callback );
}
void changed( const char* name ) const {
for ( NameCallbacks::const_iterator i = m_callbacks.begin(); i != m_callbacks.end(); ++i )
{
( *i )( name );
}
}
};
class NamedEntity : public Nameable
{
EntityKeyValues& m_entity;
NameCallbackSet m_changed;
CopiedString m_name;
EntityKeyValues& m_entity;
NameCallbackSet m_changed;
CopiedString m_name;
public:
NamedEntity(EntityKeyValues& entity) : m_entity(entity)
{
}
const char* name() const
{
if(string_empty(m_name.c_str()))
{
return m_entity.getEntityClass().name();
}
return m_name.c_str();
}
void attach(const NameCallback& callback)
{
m_changed.insert(callback);
}
void detach(const NameCallback& callback)
{
m_changed.erase(callback);
}
NamedEntity( EntityKeyValues& entity ) : m_entity( entity ){
}
const char* name() const {
if ( string_empty( m_name.c_str() ) ) {
return m_entity.getEntityClass().name();
}
return m_name.c_str();
}
void attach( const NameCallback& callback ){
m_changed.insert( callback );
}
void detach( const NameCallback& callback ){
m_changed.erase( callback );
}
void identifierChanged(const char* value)
{
if(string_empty(value))
{
m_changed.changed(m_entity.getEntityClass().name());
}
else
{
m_changed.changed(value);
}
m_name = value;
}
typedef MemberCaller1<NamedEntity, const char*, &NamedEntity::identifierChanged> IdentifierChangedCaller;
void identifierChanged( const char* value ){
if ( string_empty( value ) ) {
m_changed.changed( m_entity.getEntityClass().name() );
}
else
{
m_changed.changed( value );
}
m_name = value;
}
typedef MemberCaller1<NamedEntity, const char*, &NamedEntity::identifierChanged> IdentifierChangedCaller;
};
class RenderableNamedEntity : public OpenGLRenderable
{
const NamedEntity& m_named;
const Vector3& m_position;
const NamedEntity& m_named;
const Vector3& m_position;
public:
RenderableNamedEntity(const NamedEntity& named, const Vector3& position)
: m_named(named), m_position(position)
{
}
void render(RenderStateFlags state) const
{
glRasterPos3fv(vector3_to_array(m_position));
GlobalOpenGL().drawString(m_named.name());
}
RenderableNamedEntity( const NamedEntity& named, const Vector3& position )
: m_named( named ), m_position( position ){
}
void render( RenderStateFlags state ) const {
glRasterPos3fv( vector3_to_array( m_position ) );
GlobalOpenGL().drawString( m_named.name() );
}
};

View File

@@ -1,23 +1,22 @@
/*
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
*/
#include "namekeys.h"

View File

@@ -1,25 +1,25 @@
/*
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
*/
#if !defined(INCLUDED_NAMEKEYS_H)
#if !defined( INCLUDED_NAMEKEYS_H )
#define INCLUDED_NAMEKEYS_H
#include <stdio.h>
@@ -28,23 +28,21 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "entitylib.h"
#include "namespace.h"
inline bool string_is_integer(const char* string)
{
strtol(string, const_cast<char**>(&string), 10);
return *string == '\0';
inline bool string_is_integer( const char* string ){
strtol( string, const_cast<char**>( &string ), 10 );
return *string == '\0';
}
typedef bool (*KeyIsNameFunc)(const char* key);
typedef bool ( *KeyIsNameFunc )( const char* key );
class KeyIsName
{
public:
KeyIsNameFunc m_keyIsName;
const char* m_nameKey;
KeyIsNameFunc m_keyIsName;
const char* m_nameKey;
KeyIsName()
{
}
KeyIsName(){
}
};
@@ -54,97 +52,82 @@ typedef MemberCaller1<EntityKeyValue, const KeyObserver&, &EntityKeyValue::detac
class NameKeys : public Entity::Observer, public Namespaced
{
Namespace* m_namespace;
EntityKeyValues& m_entity;
KeyIsNameFunc m_keyIsName;
NameKeys(const NameKeys& other);
NameKeys& operator=(const NameKeys& other);
Namespace* m_namespace;
EntityKeyValues& m_entity;
KeyIsNameFunc m_keyIsName;
NameKeys( const NameKeys& other );
NameKeys& operator=( const NameKeys& other );
typedef std::map<CopiedString, EntityKeyValue*> KeyValues;
KeyValues m_keyValues;
typedef std::map<CopiedString, EntityKeyValue*> KeyValues;
KeyValues m_keyValues;
void insertName(const char* key, EntityKeyValue& value)
{
if(m_namespace != 0 && m_keyIsName(key))
{
//globalOutputStream() << "insert " << key << "\n";
m_namespace->attach(KeyValueAssignCaller(value), KeyValueAttachCaller(value));
}
}
void eraseName(const char* key, EntityKeyValue& value)
{
if(m_namespace != 0 && m_keyIsName(key))
{
//globalOutputStream() << "erase " << key << "\n";
m_namespace->detach(KeyValueAssignCaller(value), KeyValueDetachCaller(value));
}
}
void insertAll()
{
for(KeyValues::iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i)
{
insertName((*i).first.c_str(), *(*i).second);
}
}
void eraseAll()
{
for(KeyValues::iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i)
{
eraseName((*i).first.c_str(), *(*i).second);
}
}
void insertName( const char* key, EntityKeyValue& value ){
if ( m_namespace != 0 && m_keyIsName( key ) ) {
//globalOutputStream() << "insert " << key << "\n";
m_namespace->attach( KeyValueAssignCaller( value ), KeyValueAttachCaller( value ) );
}
}
void eraseName( const char* key, EntityKeyValue& value ){
if ( m_namespace != 0 && m_keyIsName( key ) ) {
//globalOutputStream() << "erase " << key << "\n";
m_namespace->detach( KeyValueAssignCaller( value ), KeyValueDetachCaller( value ) );
}
}
void insertAll(){
for ( KeyValues::iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i )
{
insertName( ( *i ).first.c_str(), *( *i ).second );
}
}
void eraseAll(){
for ( KeyValues::iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i )
{
eraseName( ( *i ).first.c_str(), *( *i ).second );
}
}
public:
NameKeys(EntityKeyValues& entity) : m_namespace(0), m_entity(entity), m_keyIsName(Static<KeyIsName>::instance().m_keyIsName)
{
m_entity.attach(*this);
}
~NameKeys()
{
m_entity.detach(*this);
}
void setNamespace(Namespace& space)
{
eraseAll();
m_namespace = &space;
insertAll();
}
void setKeyIsName(KeyIsNameFunc keyIsName)
{
eraseAll();
m_keyIsName = keyIsName;
insertAll();
}
void insert(const char* key, EntityKeyValue& value)
{
m_keyValues.insert(KeyValues::value_type(key, &value));
insertName(key, value);
}
void erase(const char* key, EntityKeyValue& value)
{
eraseName(key, value);
m_keyValues.erase(key);
}
NameKeys( EntityKeyValues& entity ) : m_namespace( 0 ), m_entity( entity ), m_keyIsName( Static<KeyIsName>::instance().m_keyIsName ){
m_entity.attach( *this );
}
~NameKeys(){
m_entity.detach( *this );
}
void setNamespace( Namespace& space ){
eraseAll();
m_namespace = &space;
insertAll();
}
void setKeyIsName( KeyIsNameFunc keyIsName ){
eraseAll();
m_keyIsName = keyIsName;
insertAll();
}
void insert( const char* key, EntityKeyValue& value ){
m_keyValues.insert( KeyValues::value_type( key, &value ) );
insertName( key, value );
}
void erase( const char* key, EntityKeyValue& value ){
eraseName( key, value );
m_keyValues.erase( key );
}
};
inline bool keyIsNameDoom3(const char* key)
{
return string_equal(key, "target")
|| (string_equal_n(key, "target", 6) && string_is_integer(key + 6))
|| string_equal(key, "name");
inline bool keyIsNameDoom3( const char* key ){
return string_equal( key, "target" )
|| ( string_equal_n( key, "target", 6 ) && string_is_integer( key + 6 ) )
|| string_equal( key, "name" );
}
inline bool keyIsNameDoom3Doom3Group(const char* key)
{
return keyIsNameDoom3(key)
|| string_equal(key, "model");
inline bool keyIsNameDoom3Doom3Group( const char* key ){
return keyIsNameDoom3( key )
|| string_equal( key, "model" );
}
inline bool keyIsNameQuake3(const char* key)
{
return string_equal(key, "target")
|| string_equal(key, "targetname")
|| string_equal(key, "killtarget")
|| (string_equal_n(key, "target", 6) && string_is_integer(key + 6)); // Nexuiz
inline bool keyIsNameQuake3( const char* key ){
return string_equal( key, "target" )
|| string_equal( key, "targetname" )
|| string_equal( key, "killtarget" )
|| ( string_equal_n( key, "target", 6 ) && string_is_integer( key + 6 ) ); // Nexuiz
}
#endif

View File

@@ -1,23 +1,22 @@
/*
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
*/
#include "origin.h"

View File

@@ -1,25 +1,25 @@
/*
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
*/
#if !defined(INCLUDED_ORIGIN_H)
#if !defined( INCLUDED_ORIGIN_H )
#define INCLUDED_ORIGIN_H
#include "ientity.h"
@@ -28,141 +28,118 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "generic/callback.h"
#include "stringio.h"
const Vector3 ORIGINKEY_IDENTITY = Vector3(0, 0, 0);
const Vector3 ORIGINKEY_IDENTITY = Vector3( 0, 0, 0 );
inline void default_origin(Vector3& origin)
{
origin = ORIGINKEY_IDENTITY;
inline void default_origin( Vector3& origin ){
origin = ORIGINKEY_IDENTITY;
}
inline void read_origin(Vector3& origin, const char* value)
{
if(!string_parse_vector3(value, origin))
{
default_origin(origin);
}
inline void read_origin( Vector3& origin, const char* value ){
if ( !string_parse_vector3( value, origin ) ) {
default_origin( origin );
}
}
inline void write_origin(const Vector3& origin, Entity* entity, const char* key)
{
char value[64];
sprintf(value, "%f %f %f", origin[0], origin[1], origin[2]);
entity->setKeyValue(key, value);
inline void write_origin( const Vector3& origin, Entity* entity, const char* key ){
char value[64];
sprintf( value, "%f %f %f", origin[0], origin[1], origin[2] );
entity->setKeyValue( key, value );
}
inline Vector3 origin_translated(const Vector3& origin, const Vector3& translation)
{
return matrix4_get_translation_vec3(
matrix4_multiplied_by_matrix4(
matrix4_translation_for_vec3(origin),
matrix4_translation_for_vec3(translation)
)
);
inline Vector3 origin_translated( const Vector3& origin, const Vector3& translation ){
return matrix4_get_translation_vec3(
matrix4_multiplied_by_matrix4(
matrix4_translation_for_vec3( origin ),
matrix4_translation_for_vec3( translation )
)
);
}
inline Vector3 origin_snapped(const Vector3& origin, float snap)
{
return vector3_snapped(origin, snap);
inline Vector3 origin_snapped( const Vector3& origin, float snap ){
return vector3_snapped( origin, snap );
}
class OriginKey
{
Callback m_originChanged;
Callback m_originChanged;
public:
Vector3 m_origin;
Vector3 m_origin;
OriginKey(const Callback& originChanged)
: m_originChanged(originChanged), m_origin(ORIGINKEY_IDENTITY)
{
}
OriginKey( const Callback& originChanged )
: m_originChanged( originChanged ), m_origin( ORIGINKEY_IDENTITY ){
}
void originChanged(const char* value)
{
read_origin(m_origin, value);
m_originChanged();
}
typedef MemberCaller1<OriginKey, const char*, &OriginKey::originChanged> OriginChangedCaller;
void originChanged( const char* value ){
read_origin( m_origin, value );
m_originChanged();
}
typedef MemberCaller1<OriginKey, const char*, &OriginKey::originChanged> OriginChangedCaller;
void write(Entity* entity) const
{
write_origin(m_origin, entity, "origin");
}
void write( Entity* entity ) const {
write_origin( m_origin, entity, "origin" );
}
};
#include "scenelib.h"
inline BrushDoom3* Node_getBrushDoom3(scene::Node& node)
{
return NodeTypeCast<BrushDoom3>::cast(node);
inline BrushDoom3* Node_getBrushDoom3( scene::Node& node ){
return NodeTypeCast<BrushDoom3>::cast( node );
}
inline void BrushDoom3_setDoom3GroupOrigin(scene::Node& node, const Vector3& origin)
{
BrushDoom3* brush = Node_getBrushDoom3(node);
if(brush != 0)
{
brush->setDoom3GroupOrigin(origin);
}
inline void BrushDoom3_setDoom3GroupOrigin( scene::Node& node, const Vector3& origin ){
BrushDoom3* brush = Node_getBrushDoom3( node );
if ( brush != 0 ) {
brush->setDoom3GroupOrigin( origin );
}
}
class SetDoom3GroupOriginWalker : public scene::Traversable::Walker
{
const Vector3& m_origin;
const Vector3& m_origin;
public:
SetDoom3GroupOriginWalker(const Vector3& origin) : m_origin(origin)
{
}
bool pre(scene::Node& node) const
{
BrushDoom3_setDoom3GroupOrigin(node, m_origin);
return true;
}
SetDoom3GroupOriginWalker( const Vector3& origin ) : m_origin( origin ){
}
bool pre( scene::Node& node ) const {
BrushDoom3_setDoom3GroupOrigin( node, m_origin );
return true;
}
};
class Doom3GroupOrigin : public scene::Traversable::Observer
{
scene::Traversable& m_set;
const Vector3& m_origin;
bool m_enabled;
scene::Traversable& m_set;
const Vector3& m_origin;
bool m_enabled;
public:
Doom3GroupOrigin(scene::Traversable& set, const Vector3& origin) : m_set(set), m_origin(origin), m_enabled(false)
{
}
Doom3GroupOrigin( scene::Traversable& set, const Vector3& origin ) : m_set( set ), m_origin( origin ), m_enabled( false ){
}
void enable()
{
m_enabled = true;
originChanged();
}
void disable()
{
m_enabled = false;
}
void enable(){
m_enabled = true;
originChanged();
}
void disable(){
m_enabled = false;
}
void originChanged()
{
if(m_enabled)
{
m_set.traverse(SetDoom3GroupOriginWalker(m_origin));
}
}
void originChanged(){
if ( m_enabled ) {
m_set.traverse( SetDoom3GroupOriginWalker( m_origin ) );
}
}
void insert(scene::Node& node)
{
if(m_enabled)
{
BrushDoom3_setDoom3GroupOrigin(node, m_origin);
}
}
void erase(scene::Node& node)
{
if(m_enabled)
{
BrushDoom3_setDoom3GroupOrigin(node, Vector3(0, 0, 0));
}
}
void insert( scene::Node& node ){
if ( m_enabled ) {
BrushDoom3_setDoom3GroupOrigin( node, m_origin );
}
}
void erase( scene::Node& node ){
if ( m_enabled ) {
BrushDoom3_setDoom3GroupOrigin( node, Vector3( 0, 0, 0 ) );
}
}
};

View File

@@ -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
*/
#include "plugin.h"
@@ -45,43 +45,40 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "modulesystem/singletonmodule.h"
class EntityDependencies :
public GlobalRadiantModuleRef,
public GlobalOpenGLModuleRef,
public GlobalUndoModuleRef,
public GlobalSceneGraphModuleRef,
public GlobalShaderCacheModuleRef,
public GlobalSelectionModuleRef,
public GlobalReferenceModuleRef,
public GlobalFilterModuleRef,
public GlobalPreferenceSystemModuleRef,
public GlobalNamespaceModuleRef,
public GlobalModelSkinCacheModuleRef
public GlobalRadiantModuleRef,
public GlobalOpenGLModuleRef,
public GlobalUndoModuleRef,
public GlobalSceneGraphModuleRef,
public GlobalShaderCacheModuleRef,
public GlobalSelectionModuleRef,
public GlobalReferenceModuleRef,
public GlobalFilterModuleRef,
public GlobalPreferenceSystemModuleRef,
public GlobalNamespaceModuleRef,
public GlobalModelSkinCacheModuleRef
{
};
class EntityQ3API : public TypeSystemRef
{
EntityCreator* m_entityq3;
EntityCreator* m_entityq3;
public:
typedef EntityCreator Type;
STRING_CONSTANT(Name, "quake3");
typedef EntityCreator Type;
STRING_CONSTANT( Name, "quake3" );
EntityQ3API()
{
Entity_Construct();
EntityQ3API(){
Entity_Construct();
m_entityq3 = &GetEntityCreator();
m_entityq3 = &GetEntityCreator();
GlobalReferenceCache().setEntityCreator(*m_entityq3);
}
~EntityQ3API()
{
Entity_Destroy();
}
EntityCreator* getTable()
{
return m_entityq3;
}
GlobalReferenceCache().setEntityCreator( *m_entityq3 );
}
~EntityQ3API(){
Entity_Destroy();
}
EntityCreator* getTable(){
return m_entityq3;
}
};
typedef SingletonModule<EntityQ3API, EntityDependencies> EntityQ3Module;
@@ -91,27 +88,24 @@ EntityQ3Module g_EntityQ3Module;
class EntityWolfAPI : public TypeSystemRef
{
EntityCreator* m_entitywolf;
EntityCreator* m_entitywolf;
public:
typedef EntityCreator Type;
STRING_CONSTANT(Name, "wolf");
typedef EntityCreator Type;
STRING_CONSTANT( Name, "wolf" );
EntityWolfAPI()
{
Entity_Construct(eGameTypeRTCW);
EntityWolfAPI(){
Entity_Construct( eGameTypeRTCW );
m_entitywolf = &GetEntityCreator();
m_entitywolf = &GetEntityCreator();
GlobalReferenceCache().setEntityCreator(*m_entitywolf);
}
~EntityWolfAPI()
{
Entity_Destroy();
}
EntityCreator* getTable()
{
return m_entitywolf;
}
GlobalReferenceCache().setEntityCreator( *m_entitywolf );
}
~EntityWolfAPI(){
Entity_Destroy();
}
EntityCreator* getTable(){
return m_entitywolf;
}
};
typedef SingletonModule<EntityWolfAPI, EntityDependencies> EntityWolfModule;
@@ -121,27 +115,24 @@ EntityWolfModule g_EntityWolfModule;
class EntityDoom3API : public TypeSystemRef
{
EntityCreator* m_entitydoom3;
EntityCreator* m_entitydoom3;
public:
typedef EntityCreator Type;
STRING_CONSTANT(Name, "doom3");
typedef EntityCreator Type;
STRING_CONSTANT( Name, "doom3" );
EntityDoom3API()
{
Entity_Construct(eGameTypeDoom3);
EntityDoom3API(){
Entity_Construct( eGameTypeDoom3 );
m_entitydoom3 = &GetEntityCreator();
m_entitydoom3 = &GetEntityCreator();
GlobalReferenceCache().setEntityCreator(*m_entitydoom3);
}
~EntityDoom3API()
{
Entity_Destroy();
}
EntityCreator* getTable()
{
return m_entitydoom3;
}
GlobalReferenceCache().setEntityCreator( *m_entitydoom3 );
}
~EntityDoom3API(){
Entity_Destroy();
}
EntityCreator* getTable(){
return m_entitydoom3;
}
};
typedef SingletonModule<EntityDoom3API, EntityDependencies> EntityDoom3Module;
@@ -149,12 +140,11 @@ typedef SingletonModule<EntityDoom3API, EntityDependencies> EntityDoom3Module;
EntityDoom3Module g_EntityDoom3Module;
extern "C" void RADIANT_DLLEXPORT Radiant_RegisterModules(ModuleServer& server)
{
initialiseModule(server);
extern "C" void RADIANT_DLLEXPORT Radiant_RegisterModules( ModuleServer& server ){
initialiseModule( server );
g_EntityQ3Module.selfRegister();
g_EntityWolfModule.selfRegister();
g_EntityDoom3Module.selfRegister();
Doom3ModelSkinCacheModule_selfRegister(server);
g_EntityQ3Module.selfRegister();
g_EntityWolfModule.selfRegister();
g_EntityDoom3Module.selfRegister();
Doom3ModelSkinCacheModule_selfRegister( server );
}

View File

@@ -1,25 +1,25 @@
/*
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
*/
#if !defined(INCLUDED_PLUGIN_H)
#if !defined( INCLUDED_PLUGIN_H )
#define INCLUDED_PLUGIN_H
#endif

View File

@@ -1,23 +1,22 @@
/*
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
*/
#include "rotation.h"

View File

@@ -1,25 +1,25 @@
/*
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
*/
#if !defined(INCLUDED_ROTATION_H)
#if !defined( INCLUDED_ROTATION_H )
#define INCLUDED_ROTATION_H
#include "ientity.h"
@@ -33,167 +33,151 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
typedef float Float9[9];
inline void default_rotation(Float9 rotation)
{
rotation[0] = 1;
rotation[1] = 0;
rotation[2] = 0;
rotation[3] = 0;
rotation[4] = 1;
rotation[5] = 0;
rotation[6] = 0;
rotation[7] = 0;
rotation[8] = 1;
inline void default_rotation( Float9 rotation ){
rotation[0] = 1;
rotation[1] = 0;
rotation[2] = 0;
rotation[3] = 0;
rotation[4] = 1;
rotation[5] = 0;
rotation[6] = 0;
rotation[7] = 0;
rotation[8] = 1;
}
inline void write_rotation(const Float9 rotation, Entity* entity, const char* key = "rotation")
{
if(rotation[0] == 1
&& rotation[1] == 0
&& rotation[2] == 0
&& rotation[3] == 0
&& rotation[4] == 1
&& rotation[5] == 0
&& rotation[6] == 0
&& rotation[7] == 0
&& rotation[8] == 1)
{
entity->setKeyValue(key, "");
}
else
{
StringOutputStream value(256);
value << rotation[0] << ' '
<< rotation[1] << ' '
<< rotation[2] << ' '
<< rotation[3] << ' '
<< rotation[4] << ' '
<< rotation[5] << ' '
<< rotation[6] << ' '
<< rotation[7] << ' '
<< rotation[8];
entity->setKeyValue(key, value.c_str());
}
inline void write_rotation( const Float9 rotation, Entity* entity, const char* key = "rotation" ){
if ( rotation[0] == 1
&& rotation[1] == 0
&& rotation[2] == 0
&& rotation[3] == 0
&& rotation[4] == 1
&& rotation[5] == 0
&& rotation[6] == 0
&& rotation[7] == 0
&& rotation[8] == 1 ) {
entity->setKeyValue( key, "" );
}
else
{
StringOutputStream value( 256 );
value << rotation[0] << ' '
<< rotation[1] << ' '
<< rotation[2] << ' '
<< rotation[3] << ' '
<< rotation[4] << ' '
<< rotation[5] << ' '
<< rotation[6] << ' '
<< rotation[7] << ' '
<< rotation[8];
entity->setKeyValue( key, value.c_str() );
}
}
inline void read_rotation(Float9 rotation, const char* value)
{
if(!string_parse_vector(value, rotation, rotation + 9))
{
default_rotation(rotation);
}
inline void read_rotation( Float9 rotation, const char* value ){
if ( !string_parse_vector( value, rotation, rotation + 9 ) ) {
default_rotation( rotation );
}
}
inline Matrix4 rotation_toMatrix(const Float9 rotation)
{
return Matrix4(
rotation[0],
rotation[1],
rotation[2],
0,
rotation[3],
rotation[4],
rotation[5],
0,
rotation[6],
rotation[7],
rotation[8],
0,
0,
0,
0,
1
);
inline Matrix4 rotation_toMatrix( const Float9 rotation ){
return Matrix4(
rotation[0],
rotation[1],
rotation[2],
0,
rotation[3],
rotation[4],
rotation[5],
0,
rotation[6],
rotation[7],
rotation[8],
0,
0,
0,
0,
1
);
}
inline void rotation_fromMatrix(Float9 rotation, const Matrix4& matrix)
{
rotation[0] = matrix.xx();
rotation[1] = matrix.xy();
rotation[2] = matrix.xz();
rotation[3] = matrix.yx();
rotation[4] = matrix.yy();
rotation[5] = matrix.yz();
rotation[6] = matrix.zx();
rotation[7] = matrix.zy();
rotation[8] = matrix.zz();
inline void rotation_fromMatrix( Float9 rotation, const Matrix4& matrix ){
rotation[0] = matrix.xx();
rotation[1] = matrix.xy();
rotation[2] = matrix.xz();
rotation[3] = matrix.yx();
rotation[4] = matrix.yy();
rotation[5] = matrix.yz();
rotation[6] = matrix.zx();
rotation[7] = matrix.zy();
rotation[8] = matrix.zz();
}
inline void rotation_assign(Float9 rotation, const Float9 other)
{
rotation[0] = other[0];
rotation[1] = other[1];
rotation[2] = other[2];
rotation[3] = other[3];
rotation[4] = other[4];
rotation[5] = other[5];
rotation[6] = other[6];
rotation[7] = other[7];
rotation[8] = other[8];
inline void rotation_assign( Float9 rotation, const Float9 other ){
rotation[0] = other[0];
rotation[1] = other[1];
rotation[2] = other[2];
rotation[3] = other[3];
rotation[4] = other[4];
rotation[5] = other[5];
rotation[6] = other[6];
rotation[7] = other[7];
rotation[8] = other[8];
}
inline void rotation_rotate(Float9 rotation, const Quaternion& rotate)
{
rotation_fromMatrix(rotation,
matrix4_multiplied_by_matrix4(
rotation_toMatrix(rotation),
matrix4_rotation_for_quaternion_quantised(rotate)
)
);
inline void rotation_rotate( Float9 rotation, const Quaternion& rotate ){
rotation_fromMatrix( rotation,
matrix4_multiplied_by_matrix4(
rotation_toMatrix( rotation ),
matrix4_rotation_for_quaternion_quantised( rotate )
)
);
}
inline void read_angle(Float9 rotation, const char* value)
{
float angle;
if(!string_parse_float(value, angle))
{
default_rotation(rotation);
}
else
{
rotation_fromMatrix(rotation, matrix4_rotation_for_z_degrees(angle));
}
inline void read_angle( Float9 rotation, const char* value ){
float angle;
if ( !string_parse_float( value, angle ) ) {
default_rotation( rotation );
}
else
{
rotation_fromMatrix( rotation, matrix4_rotation_for_z_degrees( angle ) );
}
}
class RotationKey
{
Callback m_rotationChanged;
Callback m_rotationChanged;
public:
Float9 m_rotation;
Float9 m_rotation;
RotationKey(const Callback& rotationChanged)
: m_rotationChanged(rotationChanged)
{
default_rotation(m_rotation);
}
RotationKey( const Callback& rotationChanged )
: m_rotationChanged( rotationChanged ){
default_rotation( m_rotation );
}
void angleChanged(const char* value)
{
read_angle(m_rotation, value);
m_rotationChanged();
}
typedef MemberCaller1<RotationKey, const char*, &RotationKey::angleChanged> AngleChangedCaller;
void angleChanged( const char* value ){
read_angle( m_rotation, value );
m_rotationChanged();
}
typedef MemberCaller1<RotationKey, const char*, &RotationKey::angleChanged> AngleChangedCaller;
void rotationChanged(const char* value)
{
read_rotation(m_rotation, value);
m_rotationChanged();
}
typedef MemberCaller1<RotationKey, const char*, &RotationKey::rotationChanged> RotationChangedCaller;
void rotationChanged( const char* value ){
read_rotation( m_rotation, value );
m_rotationChanged();
}
typedef MemberCaller1<RotationKey, const char*, &RotationKey::rotationChanged> RotationChangedCaller;
void write(Entity* entity) const
{
Vector3 euler = matrix4_get_rotation_euler_xyz_degrees(rotation_toMatrix(m_rotation));
if(euler[0] == 0 && euler[1] == 0)
{
entity->setKeyValue("rotation", "");
write_angle(euler[2], entity);
}
else
{
entity->setKeyValue("angle", "");
write_rotation(m_rotation, entity);
}
}
void write( Entity* entity ) const {
Vector3 euler = matrix4_get_rotation_euler_xyz_degrees( rotation_toMatrix( m_rotation ) );
if ( euler[0] == 0 && euler[1] == 0 ) {
entity->setKeyValue( "rotation", "" );
write_angle( euler[2], entity );
}
else
{
entity->setKeyValue( "angle", "" );
write_rotation( m_rotation, entity );
}
}
};
#endif

View File

@@ -1,23 +1,22 @@
/*
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
*/
#include "scale.h"

View File

@@ -1,25 +1,25 @@
/*
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
*/
#if !defined(INCLUDED_SCALE_H)
#if !defined( INCLUDED_SCALE_H )
#define INCLUDED_SCALE_H
#include "ientity.h"
@@ -28,100 +28,89 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "generic/callback.h"
#include "stringio.h"
const Vector3 SCALEKEY_IDENTITY = Vector3(1, 1, 1);
const Vector3 SCALEKEY_IDENTITY = Vector3( 1, 1, 1 );
inline void default_scale(Vector3& scale)
{
scale = SCALEKEY_IDENTITY;
inline void default_scale( Vector3& scale ){
scale = SCALEKEY_IDENTITY;
}
inline void read_scale(Vector3& scalevec, const char* value)
{
float scale;
if(!string_parse_float(value, scale)
|| scale == 0)
{
default_scale(scalevec);
}
else
{
scalevec = Vector3(scale, scale, scale);
}
inline void read_scale( Vector3& scalevec, const char* value ){
float scale;
if ( !string_parse_float( value, scale )
|| scale == 0 ) {
default_scale( scalevec );
}
else
{
scalevec = Vector3( scale, scale, scale );
}
}
inline void read_scalevec(Vector3& scale, const char* value)
{
if(!string_parse_vector3(value, scale)
|| scale[0] == 0
|| scale[1] == 0
|| scale[2] == 0)
default_scale(scale);
inline void read_scalevec( Vector3& scale, const char* value ){
if ( !string_parse_vector3( value, scale )
|| scale[0] == 0
|| scale[1] == 0
|| scale[2] == 0 ) {
default_scale( scale );
}
}
inline void write_scale(const Vector3& scale, Entity* entity)
{
if(scale[0] == 1 && scale[1] == 1 && scale[2] == 1)
{
entity->setKeyValue("modelscale", "");
entity->setKeyValue("modelscale_vec", "");
}
else
{
char value[64];
inline void write_scale( const Vector3& scale, Entity* entity ){
if ( scale[0] == 1 && scale[1] == 1 && scale[2] == 1 ) {
entity->setKeyValue( "modelscale", "" );
entity->setKeyValue( "modelscale_vec", "" );
}
else
{
char value[64];
if(scale[0] == scale[1] && scale[0] == scale[2])
{
sprintf(value, "%f", scale[0]);
entity->setKeyValue("modelscale_vec", "");
entity->setKeyValue("modelscale", value);
}
else
{
sprintf(value, "%f %f %f", scale[0], scale[1], scale[2]);
entity->setKeyValue("modelscale", "");
entity->setKeyValue("modelscale_vec", value);
}
}
if ( scale[0] == scale[1] && scale[0] == scale[2] ) {
sprintf( value, "%f", scale[0] );
entity->setKeyValue( "modelscale_vec", "" );
entity->setKeyValue( "modelscale", value );
}
else
{
sprintf( value, "%f %f %f", scale[0], scale[1], scale[2] );
entity->setKeyValue( "modelscale", "" );
entity->setKeyValue( "modelscale_vec", value );
}
}
}
inline Vector3 scale_scaled(const Vector3& scale, const Vector3& scaling)
{
return matrix4_get_scale_vec3(
matrix4_multiplied_by_matrix4(
matrix4_scale_for_vec3(scale),
matrix4_scale_for_vec3(scaling)
)
);
inline Vector3 scale_scaled( const Vector3& scale, const Vector3& scaling ){
return matrix4_get_scale_vec3(
matrix4_multiplied_by_matrix4(
matrix4_scale_for_vec3( scale ),
matrix4_scale_for_vec3( scaling )
)
);
}
class ScaleKey
{
Callback m_scaleChanged;
Callback m_scaleChanged;
public:
Vector3 m_scale;
Vector3 m_scale;
ScaleKey(const Callback& scaleChanged)
: m_scaleChanged(scaleChanged), m_scale(SCALEKEY_IDENTITY)
{
}
ScaleKey( const Callback& scaleChanged )
: m_scaleChanged( scaleChanged ), m_scale( SCALEKEY_IDENTITY ){
}
void uniformScaleChanged(const char* value)
{
read_scale(m_scale, value);
m_scaleChanged();
}
typedef MemberCaller1<ScaleKey, const char*, &ScaleKey::uniformScaleChanged> UniformScaleChangedCaller;
void uniformScaleChanged( const char* value ){
read_scale( m_scale, value );
m_scaleChanged();
}
typedef MemberCaller1<ScaleKey, const char*, &ScaleKey::uniformScaleChanged> UniformScaleChangedCaller;
void scaleChanged(const char* value)
{
read_scalevec(m_scale, value);
m_scaleChanged();
}
typedef MemberCaller1<ScaleKey, const char*, &ScaleKey::scaleChanged> ScaleChangedCaller;
void scaleChanged( const char* value ){
read_scalevec( m_scale, value );
m_scaleChanged();
}
typedef MemberCaller1<ScaleKey, const char*, &ScaleKey::scaleChanged> ScaleChangedCaller;
void write(Entity* entity) const
{
write_scale(m_scale, entity);
}
void write( Entity* entity ) const {
write_scale( m_scale, entity );
}
};

View File

@@ -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
*/
#include "skincache.h"
@@ -37,162 +37,141 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "modulesystem/singletonmodule.h"
#include "stringio.h"
void parseShaderName(CopiedString& name, const char* token)
{
StringOutputStream cleaned(256);
cleaned << PathCleaned(token);
name = cleaned.c_str();
void parseShaderName( CopiedString& name, const char* token ){
StringOutputStream cleaned( 256 );
cleaned << PathCleaned( token );
name = cleaned.c_str();
}
class Doom3ModelSkin
{
typedef std::map<CopiedString, CopiedString> Remaps;
Remaps m_remaps;
typedef std::map<CopiedString, CopiedString> Remaps;
Remaps m_remaps;
public:
bool parseTokens(Tokeniser& tokeniser)
{
RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "{"));
tokeniser.nextLine();
for(;;)
{
const char* token = tokeniser.getToken();
if(token == 0)
{
return false;
}
if(string_equal(token, "}"))
{
tokeniser.nextLine();
return true;
}
else if(string_equal(token, "model"))
{
//const char* model =
tokeniser.getToken();
}
else
{
CopiedString from, to;
parseShaderName(from, token);
bool parseTokens( Tokeniser& tokeniser ){
RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, "{" ) );
tokeniser.nextLine();
for (;; )
{
const char* token = tokeniser.getToken();
if ( token == 0 ) {
return false;
}
if ( string_equal( token, "}" ) ) {
tokeniser.nextLine();
return true;
}
else if ( string_equal( token, "model" ) ) {
//const char* model =
tokeniser.getToken();
}
else
{
CopiedString from, to;
parseShaderName( from, token );
tokeniser.nextLine(); // hack to handle badly formed skins
tokeniser.nextLine(); // hack to handle badly formed skins
parseShaderName(to, tokeniser.getToken());
parseShaderName( to, tokeniser.getToken() );
if(!string_equal(from.c_str(), to.c_str()))
{
m_remaps.insert(Remaps::value_type(from, to));
}
}
tokeniser.nextLine();
}
}
const char* getRemap(const char* name) const
{
Remaps::const_iterator i = m_remaps.find(name);
if(i != m_remaps.end())
{
return (*i).second.c_str();
}
return "";
}
void forEachRemap(const SkinRemapCallback& callback) const
{
for(Remaps::const_iterator i = m_remaps.begin(); i != m_remaps.end(); ++i)
{
callback(SkinRemap((*i).first.c_str(), (*i).second.c_str()));
}
}
if ( !string_equal( from.c_str(), to.c_str() ) ) {
m_remaps.insert( Remaps::value_type( from, to ) );
}
}
tokeniser.nextLine();
}
}
const char* getRemap( const char* name ) const {
Remaps::const_iterator i = m_remaps.find( name );
if ( i != m_remaps.end() ) {
return ( *i ).second.c_str();
}
return "";
}
void forEachRemap( const SkinRemapCallback& callback ) const {
for ( Remaps::const_iterator i = m_remaps.begin(); i != m_remaps.end(); ++i )
{
callback( SkinRemap( ( *i ).first.c_str(), ( *i ).second.c_str() ) );
}
}
};
class GlobalSkins
{
public:
typedef std::map<CopiedString, Doom3ModelSkin> SkinMap;
SkinMap m_skins;
Doom3ModelSkin g_nullSkin;
typedef std::map<CopiedString, Doom3ModelSkin> SkinMap;
SkinMap m_skins;
Doom3ModelSkin g_nullSkin;
Doom3ModelSkin& getSkin(const char* name)
{
SkinMap::iterator i = m_skins.find(name);
if(i != m_skins.end())
{
return (*i).second;
}
return g_nullSkin;
}
Doom3ModelSkin& getSkin( const char* name ){
SkinMap::iterator i = m_skins.find( name );
if ( i != m_skins.end() ) {
return ( *i ).second;
}
bool parseTokens(Tokeniser& tokeniser)
{
tokeniser.nextLine();
for(;;)
{
const char* token = tokeniser.getToken();
if(token == 0)
{
// end of token stream
return true;
}
if(!string_equal(token, "skin"))
{
Tokeniser_unexpectedError(tokeniser, token, "skin");
return false;
}
const char* other = tokeniser.getToken();
if(other == 0)
{
Tokeniser_unexpectedError(tokeniser, token, "#string");
return false;
}
CopiedString name;
parseShaderName(name, other);
Doom3ModelSkin& skin = m_skins[name];
RETURN_FALSE_IF_FAIL(skin.parseTokens(tokeniser));
}
}
return g_nullSkin;
}
void parseFile(const char* name)
{
StringOutputStream relativeName(64);
relativeName << "skins/" << name;
ArchiveTextFile* file = GlobalFileSystem().openTextFile(relativeName.c_str());
if(file != 0)
{
globalOutputStream() << "parsing skins from " << makeQuoted(name) << "\n";
{
Tokeniser& tokeniser = GlobalScriptLibrary().m_pfnNewSimpleTokeniser(file->getInputStream());
parseTokens(tokeniser);
tokeniser.release();
}
file->release();
}
else
{
globalErrorStream() << "failed to open " << makeQuoted(name) << "\n";
}
}
bool parseTokens( Tokeniser& tokeniser ){
tokeniser.nextLine();
for (;; )
{
const char* token = tokeniser.getToken();
if ( token == 0 ) {
// end of token stream
return true;
}
if ( !string_equal( token, "skin" ) ) {
Tokeniser_unexpectedError( tokeniser, token, "skin" );
return false;
}
const char* other = tokeniser.getToken();
if ( other == 0 ) {
Tokeniser_unexpectedError( tokeniser, token, "#string" );
return false;
}
CopiedString name;
parseShaderName( name, other );
Doom3ModelSkin& skin = m_skins[name];
RETURN_FALSE_IF_FAIL( skin.parseTokens( tokeniser ) );
}
}
typedef MemberCaller1<GlobalSkins, const char*, &GlobalSkins::parseFile> ParseFileCaller;
void parseFile( const char* name ){
StringOutputStream relativeName( 64 );
relativeName << "skins/" << name;
ArchiveTextFile* file = GlobalFileSystem().openTextFile( relativeName.c_str() );
if ( file != 0 ) {
globalOutputStream() << "parsing skins from " << makeQuoted( name ) << "\n";
{
Tokeniser& tokeniser = GlobalScriptLibrary().m_pfnNewSimpleTokeniser( file->getInputStream() );
parseTokens( tokeniser );
tokeniser.release();
}
file->release();
}
else
{
globalErrorStream() << "failed to open " << makeQuoted( name ) << "\n";
}
}
void construct()
{
GlobalFileSystem().forEachFile("skins/", "skin", ParseFileCaller(*this));
}
typedef MemberCaller1<GlobalSkins, const char*, &GlobalSkins::parseFile> ParseFileCaller;
void destroy()
{
m_skins.clear();
}
void construct(){
GlobalFileSystem().forEachFile( "skins/", "skin", ParseFileCaller( *this ) );
}
void realise()
{
construct();
}
void unrealise()
{
destroy();
}
void destroy(){
m_skins.clear();
}
void realise(){
construct();
}
void unrealise(){
destroy();
}
};
GlobalSkins g_skins;
@@ -200,137 +179,114 @@ GlobalSkins g_skins;
class Doom3ModelSkinCacheElement : public ModelSkin
{
ModuleObservers m_observers;
Doom3ModelSkin* m_skin;
ModuleObservers m_observers;
Doom3ModelSkin* m_skin;
public:
Doom3ModelSkinCacheElement() : m_skin(0)
{
}
void attach(ModuleObserver& observer)
{
m_observers.attach(observer);
if(realised())
{
observer.realise();
}
}
void detach(ModuleObserver& observer)
{
if(realised())
{
observer.unrealise();
}
m_observers.detach(observer);
}
bool realised() const
{
return m_skin != 0;
}
void realise(const char* name)
{
ASSERT_MESSAGE(!realised(), "Doom3ModelSkinCacheElement::realise: already realised");
m_skin = &g_skins.getSkin(name);
m_observers.realise();
}
void unrealise()
{
ASSERT_MESSAGE(realised(), "Doom3ModelSkinCacheElement::unrealise: not realised");
m_observers.unrealise();
m_skin = 0;
}
const char* getRemap(const char* name) const
{
ASSERT_MESSAGE(realised(), "Doom3ModelSkinCacheElement::getRemap: not realised");
return m_skin->getRemap(name);
}
void forEachRemap(const SkinRemapCallback& callback) const
{
ASSERT_MESSAGE(realised(), "Doom3ModelSkinCacheElement::forEachRemap: not realised");
m_skin->forEachRemap(callback);
}
Doom3ModelSkinCacheElement() : m_skin( 0 ){
}
void attach( ModuleObserver& observer ){
m_observers.attach( observer );
if ( realised() ) {
observer.realise();
}
}
void detach( ModuleObserver& observer ){
if ( realised() ) {
observer.unrealise();
}
m_observers.detach( observer );
}
bool realised() const {
return m_skin != 0;
}
void realise( const char* name ){
ASSERT_MESSAGE( !realised(), "Doom3ModelSkinCacheElement::realise: already realised" );
m_skin = &g_skins.getSkin( name );
m_observers.realise();
}
void unrealise(){
ASSERT_MESSAGE( realised(), "Doom3ModelSkinCacheElement::unrealise: not realised" );
m_observers.unrealise();
m_skin = 0;
}
const char* getRemap( const char* name ) const {
ASSERT_MESSAGE( realised(), "Doom3ModelSkinCacheElement::getRemap: not realised" );
return m_skin->getRemap( name );
}
void forEachRemap( const SkinRemapCallback& callback ) const {
ASSERT_MESSAGE( realised(), "Doom3ModelSkinCacheElement::forEachRemap: not realised" );
m_skin->forEachRemap( callback );
}
};
class Doom3ModelSkinCache : public ModelSkinCache, public ModuleObserver
{
class CreateDoom3ModelSkin
{
Doom3ModelSkinCache& m_cache;
public:
explicit CreateDoom3ModelSkin(Doom3ModelSkinCache& cache)
: m_cache(cache)
{
}
Doom3ModelSkinCacheElement* construct(const CopiedString& name)
{
Doom3ModelSkinCacheElement* skin = new Doom3ModelSkinCacheElement;
if(m_cache.realised())
{
skin->realise(name.c_str());
}
return skin;
}
void destroy(Doom3ModelSkinCacheElement* skin)
{
if(m_cache.realised())
{
skin->unrealise();
}
delete skin;
}
};
class CreateDoom3ModelSkin
{
Doom3ModelSkinCache& m_cache;
public:
explicit CreateDoom3ModelSkin( Doom3ModelSkinCache& cache )
: m_cache( cache ){
}
Doom3ModelSkinCacheElement* construct( const CopiedString& name ){
Doom3ModelSkinCacheElement* skin = new Doom3ModelSkinCacheElement;
if ( m_cache.realised() ) {
skin->realise( name.c_str() );
}
return skin;
}
void destroy( Doom3ModelSkinCacheElement* skin ){
if ( m_cache.realised() ) {
skin->unrealise();
}
delete skin;
}
};
typedef HashedCache<CopiedString, Doom3ModelSkinCacheElement, HashString, std::equal_to<CopiedString>, CreateDoom3ModelSkin> Cache;
Cache m_cache;
bool m_realised;
typedef HashedCache<CopiedString, Doom3ModelSkinCacheElement, HashString, std::equal_to<CopiedString>, CreateDoom3ModelSkin> Cache;
Cache m_cache;
bool m_realised;
public:
typedef ModelSkinCache Type;
STRING_CONSTANT(Name, "*");
ModelSkinCache* getTable()
{
return this;
}
typedef ModelSkinCache Type;
STRING_CONSTANT( Name, "*" );
ModelSkinCache* getTable(){
return this;
}
Doom3ModelSkinCache() : m_cache(CreateDoom3ModelSkin(*this)), m_realised(false)
{
GlobalFileSystem().attach(*this);
}
~Doom3ModelSkinCache()
{
GlobalFileSystem().detach(*this);
}
Doom3ModelSkinCache() : m_cache( CreateDoom3ModelSkin( *this ) ), m_realised( false ){
GlobalFileSystem().attach( *this );
}
~Doom3ModelSkinCache(){
GlobalFileSystem().detach( *this );
}
ModelSkin& capture(const char* name)
{
return *m_cache.capture(name);
}
void release(const char* name)
{
m_cache.release(name);
}
ModelSkin& capture( const char* name ){
return *m_cache.capture( name );
}
void release( const char* name ){
m_cache.release( name );
}
bool realised() const
{
return m_realised;
}
void realise()
{
g_skins.realise();
m_realised = true;
for(Cache::iterator i = m_cache.begin(); i != m_cache.end(); ++i)
{
(*i).value->realise((*i).key.c_str());
}
}
void unrealise()
{
m_realised = false;
for(Cache::iterator i = m_cache.begin(); i != m_cache.end(); ++i)
{
(*i).value->unrealise();
}
g_skins.unrealise();
}
bool realised() const {
return m_realised;
}
void realise(){
g_skins.realise();
m_realised = true;
for ( Cache::iterator i = m_cache.begin(); i != m_cache.end(); ++i )
{
( *i ).value->realise( ( *i ).key.c_str() );
}
}
void unrealise(){
m_realised = false;
for ( Cache::iterator i = m_cache.begin(); i != m_cache.end(); ++i )
{
( *i ).value->unrealise();
}
g_skins.unrealise();
}
};
class Doom3ModelSkinCacheDependencies : public GlobalFileSystemModuleRef, public GlobalScripLibModuleRef
@@ -341,8 +297,6 @@ typedef SingletonModule<Doom3ModelSkinCache, Doom3ModelSkinCacheDependencies> Do
Doom3ModelSkinCacheModule g_Doom3ModelSkinCacheModule;
void Doom3ModelSkinCacheModule_selfRegister(ModuleServer& server)
{
g_Doom3ModelSkinCacheModule.selfRegister();
void Doom3ModelSkinCacheModule_selfRegister( ModuleServer& server ){
g_Doom3ModelSkinCacheModule.selfRegister();
}

View File

@@ -1,28 +1,28 @@
/*
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
*/
#if !defined(INCLUDED_SKINCACHE_H)
#if !defined( INCLUDED_SKINCACHE_H )
#define INCLUDED_SKINCACHE_H
class ModuleServer;
void Doom3ModelSkinCacheModule_selfRegister(ModuleServer& server);
void Doom3ModelSkinCacheModule_selfRegister( ModuleServer& server );
#endif

View File

@@ -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
*/
#include "targetable.h"
@@ -27,11 +27,11 @@ const char* g_targetable_nameKey = "targetname";
targetnames_t g_targetnames;
targetables_t* getTargetables(const char* targetname)
{
if(targetname[0] == '\0')
return 0;
return &g_targetnames[targetname];
targetables_t* getTargetables( const char* targetname ){
if ( targetname[0] == '\0' ) {
return 0;
}
return &g_targetnames[targetname];
}
Shader* RenderableTargetingEntity::m_state;

View File

@@ -1,25 +1,25 @@
/*
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
*/
#if !defined(INCLUDED_TARGETABLE_H)
#if !defined( INCLUDED_TARGETABLE_H )
#define INCLUDED_TARGETABLE_H
#include <set>
@@ -39,417 +39,360 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
class Targetable
{
public:
virtual const Vector3& world_position() const = 0;
virtual const Vector3& world_position() const = 0;
};
typedef std::set<Targetable*> targetables_t;
extern const char* g_targetable_nameKey;
targetables_t* getTargetables(const char* targetname);
targetables_t* getTargetables( const char* targetname );
class EntityConnectionLine : public OpenGLRenderable
{
public:
Vector3 start;
Vector3 end;
Vector3 start;
Vector3 end;
void render(RenderStateFlags state) const
{
float s1[2], s2[2];
Vector3 dir(vector3_subtracted(end, start));
double len = vector3_length(dir);
vector3_scale(dir, 8.0 * (1.0 / len));
s1[0] = dir[0] - dir[1];
s1[1] = dir[0] + dir[1];
s2[0] = dir[0] + dir[1];
s2[1] = -dir[0] + dir[1];
glBegin(GL_LINES);
void render( RenderStateFlags state ) const {
float s1[2], s2[2];
Vector3 dir( vector3_subtracted( end, start ) );
double len = vector3_length( dir );
vector3_scale( dir, 8.0 * ( 1.0 / len ) );
s1[0] = dir[0] - dir[1];
s1[1] = dir[0] + dir[1];
s2[0] = dir[0] + dir[1];
s2[1] = -dir[0] + dir[1];
glVertex3fv(vector3_to_array(start));
glVertex3fv(vector3_to_array(end));
glBegin( GL_LINES );
len*=0.0625; // half / 8
glVertex3fv( vector3_to_array( start ) );
glVertex3fv( vector3_to_array( end ) );
Vector3 arrow(start);
for (unsigned int i = 0, count = (len<32)? 1 : static_cast<unsigned int>(len*0.0625); i < count; i++)
{
vector3_add(arrow, vector3_scaled(dir, (len<32)?len:32));
glVertex3fv(vector3_to_array(arrow));
glVertex3f(arrow[0]+s1[0], arrow[1]+s1[1], arrow[2]+dir[2]);
glVertex3fv(vector3_to_array(arrow));
glVertex3f(arrow[0]+s2[0], arrow[1]+s2[1], arrow[2]+dir[2]);
}
glEnd();
}
len *= 0.0625; // half / 8
Vector3 arrow( start );
for ( unsigned int i = 0, count = ( len < 32 ) ? 1 : static_cast<unsigned int>( len * 0.0625 ); i < count; i++ )
{
vector3_add( arrow, vector3_scaled( dir, ( len < 32 ) ? len : 32 ) );
glVertex3fv( vector3_to_array( arrow ) );
glVertex3f( arrow[0] + s1[0], arrow[1] + s1[1], arrow[2] + dir[2] );
glVertex3fv( vector3_to_array( arrow ) );
glVertex3f( arrow[0] + s2[0], arrow[1] + s2[1], arrow[2] + dir[2] );
}
glEnd();
}
};
class TargetedEntity
{
Targetable& m_targetable;
targetables_t* m_targets;
Targetable& m_targetable;
targetables_t* m_targets;
void construct()
{
if(m_targets != 0)
m_targets->insert(&m_targetable);
}
void destroy()
{
if(m_targets != 0)
m_targets->erase(&m_targetable);
}
void construct(){
if ( m_targets != 0 ) {
m_targets->insert( &m_targetable );
}
}
void destroy(){
if ( m_targets != 0 ) {
m_targets->erase( &m_targetable );
}
}
public:
TargetedEntity(Targetable& targetable)
: m_targetable(targetable), m_targets(getTargetables(""))
{
construct();
}
~TargetedEntity()
{
destroy();
}
void targetnameChanged(const char* name)
{
destroy();
m_targets = getTargetables(name);
construct();
}
typedef MemberCaller1<TargetedEntity, const char*, &TargetedEntity::targetnameChanged> TargetnameChangedCaller;
TargetedEntity( Targetable& targetable )
: m_targetable( targetable ), m_targets( getTargetables( "" ) ){
construct();
}
~TargetedEntity(){
destroy();
}
void targetnameChanged( const char* name ){
destroy();
m_targets = getTargetables( name );
construct();
}
typedef MemberCaller1<TargetedEntity, const char*, &TargetedEntity::targetnameChanged> TargetnameChangedCaller;
};
class TargetingEntity
{
targetables_t* m_targets;
targetables_t* m_targets;
public:
TargetingEntity() :
m_targets(getTargetables(""))
{
}
void targetChanged(const char* target)
{
m_targets = getTargetables(target);
}
typedef MemberCaller1<TargetingEntity, const char*, &TargetingEntity::targetChanged> TargetChangedCaller;
TargetingEntity() :
m_targets( getTargetables( "" ) ){
}
void targetChanged( const char* target ){
m_targets = getTargetables( target );
}
typedef MemberCaller1<TargetingEntity, const char*, &TargetingEntity::targetChanged> TargetChangedCaller;
typedef targetables_t::iterator iterator;
typedef targetables_t::iterator iterator;
iterator begin() const
{
if(m_targets == 0)
{
return iterator();
}
return m_targets->begin();
}
iterator end() const
{
if(m_targets == 0)
{
return iterator();
}
return m_targets->end();
}
size_t size() const
{
if(m_targets == 0)
{
return 0;
}
return m_targets->size();
}
bool empty() const
{
return m_targets == 0 || m_targets->empty();
}
iterator begin() const {
if ( m_targets == 0 ) {
return iterator();
}
return m_targets->begin();
}
iterator end() const {
if ( m_targets == 0 ) {
return iterator();
}
return m_targets->end();
}
size_t size() const {
if ( m_targets == 0 ) {
return 0;
}
return m_targets->size();
}
bool empty() const {
return m_targets == 0 || m_targets->empty();
}
};
template<typename Functor>
void TargetingEntity_forEach(const TargetingEntity& targets, const Functor& functor)
{
for(TargetingEntity::iterator i = targets.begin(); i != targets.end(); ++i)
{
functor((*i)->world_position());
}
void TargetingEntity_forEach( const TargetingEntity& targets, const Functor& functor ){
for ( TargetingEntity::iterator i = targets.begin(); i != targets.end(); ++i )
{
functor( ( *i )->world_position() );
}
}
typedef std::map<std::size_t, TargetingEntity> TargetingEntities;
template<typename Functor>
void TargetingEntities_forEach(const TargetingEntities& targetingEntities, const Functor& functor)
{
for(TargetingEntities::const_iterator i = targetingEntities.begin(); i != targetingEntities.end(); ++i)
{
TargetingEntity_forEach((*i).second, functor);
}
void TargetingEntities_forEach( const TargetingEntities& targetingEntities, const Functor& functor ){
for ( TargetingEntities::const_iterator i = targetingEntities.begin(); i != targetingEntities.end(); ++i )
{
TargetingEntity_forEach( ( *i ).second, functor );
}
}
class TargetLinesPushBack
{
RenderablePointVector& m_targetLines;
const Vector3& m_worldPosition;
const VolumeTest& m_volume;
RenderablePointVector& m_targetLines;
const Vector3& m_worldPosition;
const VolumeTest& m_volume;
public:
TargetLinesPushBack(RenderablePointVector& targetLines, const Vector3& worldPosition, const VolumeTest& volume) :
m_targetLines(targetLines), m_worldPosition(worldPosition), m_volume(volume)
{
}
void operator()(const Vector3& worldPosition) const
{
if(m_volume.TestLine(segment_for_startend(m_worldPosition, worldPosition)))
{
m_targetLines.push_back(PointVertex(reinterpret_cast<const Vertex3f&>(m_worldPosition)));
m_targetLines.push_back(PointVertex(reinterpret_cast<const Vertex3f&>(worldPosition)));
}
}
TargetLinesPushBack( RenderablePointVector& targetLines, const Vector3& worldPosition, const VolumeTest& volume ) :
m_targetLines( targetLines ), m_worldPosition( worldPosition ), m_volume( volume ){
}
void operator()( const Vector3& worldPosition ) const {
if ( m_volume.TestLine( segment_for_startend( m_worldPosition, worldPosition ) ) ) {
m_targetLines.push_back( PointVertex( reinterpret_cast<const Vertex3f&>( m_worldPosition ) ) );
m_targetLines.push_back( PointVertex( reinterpret_cast<const Vertex3f&>( worldPosition ) ) );
}
}
};
class TargetKeys : public Entity::Observer
{
TargetingEntities m_targetingEntities;
Callback m_targetsChanged;
TargetingEntities m_targetingEntities;
Callback m_targetsChanged;
bool readTargetKey(const char* key, std::size_t& index)
{
if(string_equal_n(key, "target", 6))
{
index = 0;
if(string_empty(key + 6) || string_parse_size(key + 6, index))
{
return true;
}
}
if(string_equal(key, "killtarget"))
{
index = -1;
return true;
}
return false;
}
bool readTargetKey( const char* key, std::size_t& index ){
if ( string_equal_n( key, "target", 6 ) ) {
index = 0;
if ( string_empty( key + 6 ) || string_parse_size( key + 6, index ) ) {
return true;
}
}
if ( string_equal( key, "killtarget" ) ) {
index = -1;
return true;
}
return false;
}
public:
void setTargetsChanged(const Callback& targetsChanged)
{
m_targetsChanged = targetsChanged;
}
void targetsChanged()
{
m_targetsChanged();
}
void setTargetsChanged( const Callback& targetsChanged ){
m_targetsChanged = targetsChanged;
}
void targetsChanged(){
m_targetsChanged();
}
void insert(const char* key, EntityKeyValue& value)
{
std::size_t index;
if(readTargetKey(key, index))
{
TargetingEntities::iterator i = m_targetingEntities.insert(TargetingEntities::value_type(index, TargetingEntity())).first;
value.attach(TargetingEntity::TargetChangedCaller((*i).second));
targetsChanged();
}
}
void erase(const char* key, EntityKeyValue& value)
{
std::size_t index;
if(readTargetKey(key, index))
{
TargetingEntities::iterator i = m_targetingEntities.find(index);
value.detach(TargetingEntity::TargetChangedCaller((*i).second));
m_targetingEntities.erase(i);
targetsChanged();
}
}
const TargetingEntities& get() const
{
return m_targetingEntities;
}
void insert( const char* key, EntityKeyValue& value ){
std::size_t index;
if ( readTargetKey( key, index ) ) {
TargetingEntities::iterator i = m_targetingEntities.insert( TargetingEntities::value_type( index, TargetingEntity() ) ).first;
value.attach( TargetingEntity::TargetChangedCaller( ( *i ).second ) );
targetsChanged();
}
}
void erase( const char* key, EntityKeyValue& value ){
std::size_t index;
if ( readTargetKey( key, index ) ) {
TargetingEntities::iterator i = m_targetingEntities.find( index );
value.detach( TargetingEntity::TargetChangedCaller( ( *i ).second ) );
m_targetingEntities.erase( i );
targetsChanged();
}
}
const TargetingEntities& get() const {
return m_targetingEntities;
}
};
class RenderableTargetingEntity
{
TargetingEntity& m_targets;
mutable RenderablePointVector m_target_lines;
TargetingEntity& m_targets;
mutable RenderablePointVector m_target_lines;
public:
static Shader* m_state;
static Shader* m_state;
RenderableTargetingEntity(TargetingEntity& targets)
: m_targets(targets), m_target_lines(GL_LINES)
{
}
void compile(const VolumeTest& volume, const Vector3& world_position) const
{
m_target_lines.clear();
m_target_lines.reserve(m_targets.size() * 2);
TargetingEntity_forEach(m_targets, TargetLinesPushBack(m_target_lines, world_position, volume));
}
void render(Renderer& renderer, const VolumeTest& volume, const Vector3& world_position) const
{
if(!m_targets.empty())
{
compile(volume, world_position);
if(!m_target_lines.empty())
{
renderer.addRenderable(m_target_lines, g_matrix4_identity);
}
}
}
RenderableTargetingEntity( TargetingEntity& targets )
: m_targets( targets ), m_target_lines( GL_LINES ){
}
void compile( const VolumeTest& volume, const Vector3& world_position ) const {
m_target_lines.clear();
m_target_lines.reserve( m_targets.size() * 2 );
TargetingEntity_forEach( m_targets, TargetLinesPushBack( m_target_lines, world_position, volume ) );
}
void render( Renderer& renderer, const VolumeTest& volume, const Vector3& world_position ) const {
if ( !m_targets.empty() ) {
compile( volume, world_position );
if ( !m_target_lines.empty() ) {
renderer.addRenderable( m_target_lines, g_matrix4_identity );
}
}
}
};
class RenderableTargetingEntities
{
const TargetingEntities& m_targets;
mutable RenderablePointVector m_target_lines;
const TargetingEntities& m_targets;
mutable RenderablePointVector m_target_lines;
public:
static Shader* m_state;
static Shader* m_state;
RenderableTargetingEntities(const TargetingEntities& targets)
: m_targets(targets), m_target_lines(GL_LINES)
{
}
void compile(const VolumeTest& volume, const Vector3& world_position) const
{
m_target_lines.clear();
TargetingEntities_forEach(m_targets, TargetLinesPushBack(m_target_lines, world_position, volume));
}
void render(Renderer& renderer, const VolumeTest& volume, const Vector3& world_position) const
{
if(!m_targets.empty())
{
compile(volume, world_position);
if(!m_target_lines.empty())
{
renderer.addRenderable(m_target_lines, g_matrix4_identity);
}
}
}
RenderableTargetingEntities( const TargetingEntities& targets )
: m_targets( targets ), m_target_lines( GL_LINES ){
}
void compile( const VolumeTest& volume, const Vector3& world_position ) const {
m_target_lines.clear();
TargetingEntities_forEach( m_targets, TargetLinesPushBack( m_target_lines, world_position, volume ) );
}
void render( Renderer& renderer, const VolumeTest& volume, const Vector3& world_position ) const {
if ( !m_targets.empty() ) {
compile( volume, world_position );
if ( !m_target_lines.empty() ) {
renderer.addRenderable( m_target_lines, g_matrix4_identity );
}
}
}
};
class TargetableInstance :
public SelectableInstance,
public Targetable,
public Entity::Observer
public SelectableInstance,
public Targetable,
public Entity::Observer
{
mutable Vertex3f m_position;
EntityKeyValues& m_entity;
TargetKeys m_targeting;
TargetedEntity m_targeted;
RenderableTargetingEntities m_renderable;
mutable Vertex3f m_position;
EntityKeyValues& m_entity;
TargetKeys m_targeting;
TargetedEntity m_targeted;
RenderableTargetingEntities m_renderable;
public:
TargetableInstance(
const scene::Path& path,
scene::Instance* parent,
void* instance,
InstanceTypeCastTable& casts,
EntityKeyValues& entity,
Targetable& targetable
) :
SelectableInstance(path, parent, instance, casts),
m_entity(entity),
m_targeted(targetable),
m_renderable(m_targeting.get())
{
m_entity.attach(*this);
m_entity.attach(m_targeting);
}
~TargetableInstance()
{
m_entity.detach(m_targeting);
m_entity.detach(*this);
}
TargetableInstance(
const scene::Path& path,
scene::Instance* parent,
void* instance,
InstanceTypeCastTable& casts,
EntityKeyValues& entity,
Targetable& targetable
) :
SelectableInstance( path, parent, instance, casts ),
m_entity( entity ),
m_targeted( targetable ),
m_renderable( m_targeting.get() ){
m_entity.attach( *this );
m_entity.attach( m_targeting );
}
~TargetableInstance(){
m_entity.detach( m_targeting );
m_entity.detach( *this );
}
void setTargetsChanged(const Callback& targetsChanged)
{
m_targeting.setTargetsChanged(targetsChanged);
}
void targetsChanged()
{
m_targeting.targetsChanged();
}
void setTargetsChanged( const Callback& targetsChanged ){
m_targeting.setTargetsChanged( targetsChanged );
}
void targetsChanged(){
m_targeting.targetsChanged();
}
void insert(const char* key, EntityKeyValue& value)
{
if(string_equal(key, g_targetable_nameKey))
{
value.attach(TargetedEntity::TargetnameChangedCaller(m_targeted));
}
}
void erase(const char* key, EntityKeyValue& value)
{
if(string_equal(key, g_targetable_nameKey))
{
value.detach(TargetedEntity::TargetnameChangedCaller(m_targeted));
}
}
void insert( const char* key, EntityKeyValue& value ){
if ( string_equal( key, g_targetable_nameKey ) ) {
value.attach( TargetedEntity::TargetnameChangedCaller( m_targeted ) );
}
}
void erase( const char* key, EntityKeyValue& value ){
if ( string_equal( key, g_targetable_nameKey ) ) {
value.detach( TargetedEntity::TargetnameChangedCaller( m_targeted ) );
}
}
const Vector3& world_position() const
{
const Vector3& world_position() const {
#if 1
const AABB& bounds = Instance::worldAABB();
if(aabb_valid(bounds))
{
return bounds.origin;
}
const AABB& bounds = Instance::worldAABB();
if ( aabb_valid( bounds ) ) {
return bounds.origin;
}
#else
const AABB& childBounds = Instance::childBounds();
if(aabb_valid(childBounds))
{
return childBounds.origin;
}
const AABB& childBounds = Instance::childBounds();
if ( aabb_valid( childBounds ) ) {
return childBounds.origin;
}
#endif
return vector4_to_vector3(localToWorld().t());
}
return vector4_to_vector3( localToWorld().t() );
}
void render(Renderer& renderer, const VolumeTest& volume) const
{
renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly);
renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eFullMaterials);
m_renderable.render(renderer, volume, world_position());
}
void render( Renderer& renderer, const VolumeTest& volume ) const {
renderer.SetState( m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly );
renderer.SetState( m_entity.getEntityClass().m_state_wire, Renderer::eFullMaterials );
m_renderable.render( renderer, volume, world_position() );
}
const TargetingEntities& getTargeting() const
{
return m_targeting.get();
}
const TargetingEntities& getTargeting() const {
return m_targeting.get();
}
};
class RenderableConnectionLines : public Renderable
{
typedef std::set<TargetableInstance*> TargetableInstances;
TargetableInstances m_instances;
typedef std::set<TargetableInstance*> TargetableInstances;
TargetableInstances m_instances;
public:
void attach(TargetableInstance& instance)
{
ASSERT_MESSAGE(m_instances.find(&instance) == m_instances.end(), "cannot attach instance");
m_instances.insert(&instance);
}
void detach(TargetableInstance& instance)
{
ASSERT_MESSAGE(m_instances.find(&instance) != m_instances.end(), "cannot detach instance");
m_instances.erase(&instance);
}
void attach( TargetableInstance& instance ){
ASSERT_MESSAGE( m_instances.find( &instance ) == m_instances.end(), "cannot attach instance" );
m_instances.insert( &instance );
}
void detach( TargetableInstance& instance ){
ASSERT_MESSAGE( m_instances.find( &instance ) != m_instances.end(), "cannot detach instance" );
m_instances.erase( &instance );
}
void renderSolid(Renderer& renderer, const VolumeTest& volume) const
{
for(TargetableInstances::const_iterator i = m_instances.begin(); i != m_instances.end(); ++i)
{
if((*i)->path().top().get().visible())
{
(*i)->render(renderer, volume);
}
}
}
void renderWireframe(Renderer& renderer, const VolumeTest& volume) const
{
renderSolid(renderer, volume);
}
void renderSolid( Renderer& renderer, const VolumeTest& volume ) const {
for ( TargetableInstances::const_iterator i = m_instances.begin(); i != m_instances.end(); ++i )
{
if ( ( *i )->path().top().get().visible() ) {
( *i )->render( renderer, volume );
}
}
}
void renderWireframe( Renderer& renderer, const VolumeTest& volume ) const {
renderSolid( renderer, volume );
}
};
typedef Static<RenderableConnectionLines> StaticRenderableConnectionLines;