]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - plugins/entity/eclassmodel.cpp
uncrustify! now the code is only ugly on the *inside*
[xonotic/netradiant.git] / plugins / entity / eclassmodel.cpp
1 /*
2    Copyright (C) 1999-2007 id Software, Inc. and contributors.
3    For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5    This file is part of GtkRadiant.
6
7    GtkRadiant is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    GtkRadiant is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GtkRadiant; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21
22 #include <stdlib.h>
23
24 #include "entity_entitymodel.h"
25
26 //
27 // CEntityEclassModel implementation
28 //
29
30 CEntityEclassModel::CEntityEclassModel (){
31         refCount = 1;
32         m_eclass = NULL;
33         m_model = NULL;
34         VectorSet( m_translate, 0,0,0 );
35         VectorSet( m_euler, 0,0,0 );
36         VectorSet( m_scale, 1,1,1 );
37         VectorSet( m_pivot, 0,0,0 );
38         m4x4_identity( m_transform );
39         m4x4_identity( m_inverse_transform );
40 }
41
42 CEntityEclassModel::~CEntityEclassModel (){
43         if ( m_name.c_str()[0] != '\0'
44                  && m_version.c_str()[0] != '\0' ) {
45                 GetModelCache()->DeleteByID( m_name.c_str(), m_version.c_str() );
46         }
47 }
48
49
50 // IRender
51
52 void CEntityEclassModel::Draw( int state, int rflags ) const {
53         // push the current modelview matrix
54         // FIXME: put in a check for stack recursion depth..
55         // or avoid recursion of opengl matrix stack
56         g_QglTable.m_pfn_qglPushMatrix();
57         // apply the parent-to-local transform
58         g_QglTable.m_pfn_qglMultMatrixf( m_transform );
59
60         // draw children
61         if ( m_model && m_model->pRender ) {
62                 m_model->pRender->Draw( state, rflags );
63         }
64
65         g_QglTable.m_pfn_qglPopMatrix();
66 }
67
68 // ISelect
69
70 bool CEntityEclassModel::TestRay( const ray_t *ray, vec_t *dist ) const {
71         vec_t dist_start = *dist;
72         vec_t dist_local = *dist;
73         ray_t ray_local = *ray;
74
75         if ( aabb_intersect_ray( &m_BBox, &ray_local, &dist_local ) ) {
76                 *dist = dist_local;
77         }
78         return *dist < dist_start;
79 }
80
81
82 //IEdit
83
84 void CEntityEclassModel::Translate( const vec3_t translation ){
85         VectorIncrement( translation, m_translate );
86         UpdateCachedData();
87 }
88
89 void CEntityEclassModel::Rotate( const vec3_t pivot, const vec3_t rotation ){
90         m4x4_t rotation_matrix;
91
92         m4x4_identity( rotation_matrix );
93         m4x4_pivoted_rotate_by_vec3( rotation_matrix, rotation, eXYZ, pivot );
94         m4x4_transform_point( rotation_matrix, m_translate );
95
96         VectorIncrement( rotation, m_euler );
97
98         UpdateCachedData();
99 }
100
101 void CEntityEclassModel::OnKeyValueChanged( entity_t *e, const char *key, const char* value ){
102         if ( strcmp( key,"origin" ) == 0 ) {
103                 sscanf( value, "%f %f %f", &m_translate[0], &m_translate[1], &m_translate[2] );
104                 UpdateCachedData();
105         }
106         else if ( strcmp( key,"angle" ) == 0 ) {
107                 VectorSet( m_euler, 0, 0, (float) atof( value ) );
108                 UpdateCachedData();
109         }
110 }
111
112 void CEntityEclassModel::SetEclass( const eclass_t* eclass ){
113         m_eclass = eclass;
114 }
115
116 void CEntityEclassModel::SetName( const char *name ){
117         if ( strcmp( m_name.c_str(), name ) == 0 ) {
118                 return;
119         }
120
121         if ( m_name.c_str()[0] != '\0'
122                  && m_version.c_str()[0] != '\0' ) {
123                 GetModelCache()->DeleteByID( m_name.c_str(), m_version.c_str() );
124         }
125
126         m_model = NULL;
127         m_name = name;
128
129         if ( m_name.c_str()[0] != '\0' ) {
130                 const char* dot = strrchr( m_name.c_str(), '.' );
131                 if ( dot != NULL ) {
132                         m_version = ++dot;
133                         m_model = GetModelCache()->GetByID( m_name.c_str(), m_version.c_str() );
134                 }
135         }
136
137         UpdateCachedData();
138 }
139
140 //
141 // CEntityEclassModel
142 //
143
144 // private:
145
146 void CEntityEclassModel::UpdateCachedData(){
147         aabb_t aabb_temp;
148
149         aabb_clear( &aabb_temp );
150
151         m4x4_identity( m_transform );
152         m4x4_pivoted_transform_by_vec3( m_transform, m_translate, m_euler, eXYZ, m_scale, m_pivot );
153         memcpy( m_inverse_transform, m_transform, sizeof( m4x4_t ) );
154         if ( m4x4_invert( m_inverse_transform ) == 1 ) {
155                 Sys_Printf( "ERROR: Singular Matrix, cannot invert" );
156         }
157
158         if ( m_eclass ) {
159                 aabb_construct_for_vec3( &aabb_temp, m_eclass->mins, m_eclass->maxs );
160         }
161         else{
162                 VectorSet( aabb_temp.extents, 8, 8, 8 );
163         }
164
165         aabb_for_transformed_aabb( &m_BBox, &aabb_temp, m_transform );
166 }