]> icculus.org git repositories - icculus/iodoom3.git/blob - neo/renderer/Model_beam.cpp
Use the same OpenAL headers on all platforms.
[icculus/iodoom3.git] / neo / renderer / Model_beam.cpp
1 /*
2 ===========================================================================
3
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. 
6
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).  
8
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code.  If not, see <http://www.gnu.org/licenses/>.
21
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code.  If not, please request a copy in writing from id Software at the address below.
23
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25
26 ===========================================================================
27 */
28
29 #include "../idlib/precompiled.h"
30 #pragma hdrstop
31
32 #include "tr_local.h"
33 #include "Model_local.h"
34
35 /*
36
37 This is a simple dynamic model that just creates a stretched quad between
38 two points that faces the view, like a dynamic deform tube.
39
40 */
41
42 static const char *beam_SnapshotName = "_beam_Snapshot_";
43
44 /*
45 ===============
46 idRenderModelBeam::IsDynamicModel
47 ===============
48 */
49 dynamicModel_t idRenderModelBeam::IsDynamicModel() const {
50         return DM_CONTINUOUS;   // regenerate for every view
51 }
52
53 /*
54 ===============
55 idRenderModelBeam::IsLoaded
56 ===============
57 */
58 bool idRenderModelBeam::IsLoaded() const {
59         return true;    // don't ever need to load
60 }
61
62 /*
63 ===============
64 idRenderModelBeam::InstantiateDynamicModel
65 ===============
66 */
67 idRenderModel *idRenderModelBeam::InstantiateDynamicModel( const struct renderEntity_s *renderEntity, const struct viewDef_s *viewDef, idRenderModel *cachedModel ) {
68         idRenderModelStatic *staticModel;
69         srfTriangles_t *tri;
70         modelSurface_t surf;
71
72         if ( cachedModel ) {
73                 delete cachedModel;
74                 cachedModel = NULL;
75         }
76
77         if ( renderEntity == NULL || viewDef == NULL ) {
78                 delete cachedModel;
79                 return NULL;
80         }
81
82         if ( cachedModel != NULL ) {
83
84                 assert( dynamic_cast<idRenderModelStatic *>( cachedModel ) != NULL );
85                 assert( idStr::Icmp( cachedModel->Name(), beam_SnapshotName ) == 0 );
86
87                 staticModel = static_cast<idRenderModelStatic *>( cachedModel );
88                 surf = *staticModel->Surface( 0 );
89                 tri = surf.geometry;
90
91         } else {
92
93                 staticModel = new idRenderModelStatic;
94                 staticModel->InitEmpty( beam_SnapshotName );
95
96                 tri = R_AllocStaticTriSurf();
97                 R_AllocStaticTriSurfVerts( tri, 4 );
98                 R_AllocStaticTriSurfIndexes( tri, 6 );
99
100                 tri->verts[0].Clear();
101                 tri->verts[0].st[0] = 0;
102                 tri->verts[0].st[1] = 0;
103
104                 tri->verts[1].Clear();
105                 tri->verts[1].st[0] = 0;
106                 tri->verts[1].st[1] = 1;
107
108                 tri->verts[2].Clear();
109                 tri->verts[2].st[0] = 1;
110                 tri->verts[2].st[1] = 0;
111
112                 tri->verts[3].Clear();
113                 tri->verts[3].st[0] = 1;
114                 tri->verts[3].st[1] = 1;
115
116                 tri->indexes[0] = 0;
117                 tri->indexes[1] = 2;
118                 tri->indexes[2] = 1;
119                 tri->indexes[3] = 2;
120                 tri->indexes[4] = 3;
121                 tri->indexes[5] = 1;
122
123                 tri->numVerts = 4;
124                 tri->numIndexes = 6;
125
126                 surf.geometry = tri;
127                 surf.id = 0;
128                 surf.shader = tr.defaultMaterial;
129                 staticModel->AddSurface( surf );
130         }
131
132         idVec3  target = *reinterpret_cast<const idVec3 *>( &renderEntity->shaderParms[SHADERPARM_BEAM_END_X] );
133
134         // we need the view direction to project the minor axis of the tube
135         // as the view changes
136         idVec3  localView, localTarget;
137         float   modelMatrix[16];
138         R_AxisToModelMatrix( renderEntity->axis, renderEntity->origin, modelMatrix );
139         R_GlobalPointToLocal( modelMatrix, viewDef->renderView.vieworg, localView ); 
140         R_GlobalPointToLocal( modelMatrix, target, localTarget ); 
141
142         idVec3  major = localTarget;
143         idVec3  minor;
144
145         idVec3  mid = 0.5f * localTarget;
146         idVec3  dir = mid - localView;
147         minor.Cross( major, dir );
148         minor.Normalize();
149         if ( renderEntity->shaderParms[SHADERPARM_BEAM_WIDTH] != 0.0f ) {
150                 minor *= renderEntity->shaderParms[SHADERPARM_BEAM_WIDTH] * 0.5f;
151         }
152
153         int red         = idMath::FtoiFast( renderEntity->shaderParms[SHADERPARM_RED] * 255.0f );
154         int green       = idMath::FtoiFast( renderEntity->shaderParms[SHADERPARM_GREEN] * 255.0f );
155         int blue        = idMath::FtoiFast( renderEntity->shaderParms[SHADERPARM_BLUE] * 255.0f );
156         int alpha       = idMath::FtoiFast( renderEntity->shaderParms[SHADERPARM_ALPHA] * 255.0f );
157
158         tri->verts[0].xyz = minor;
159         tri->verts[0].color[0] = red;
160         tri->verts[0].color[1] = green;
161         tri->verts[0].color[2] = blue;
162         tri->verts[0].color[3] = alpha;
163
164         tri->verts[1].xyz = -minor;
165         tri->verts[1].color[0] = red;
166         tri->verts[1].color[1] = green;
167         tri->verts[1].color[2] = blue;
168         tri->verts[1].color[3] = alpha;
169
170         tri->verts[2].xyz = localTarget + minor;
171         tri->verts[2].color[0] = red;
172         tri->verts[2].color[1] = green;
173         tri->verts[2].color[2] = blue;
174         tri->verts[2].color[3] = alpha;
175
176         tri->verts[3].xyz = localTarget - minor;
177         tri->verts[3].color[0] = red;
178         tri->verts[3].color[1] = green;
179         tri->verts[3].color[2] = blue;
180         tri->verts[3].color[3] = alpha;
181
182         R_BoundTriSurf( tri );
183
184         staticModel->bounds = tri->bounds;
185
186         return staticModel;
187 }
188
189 /*
190 ===============
191 idRenderModelBeam::Bounds
192 ===============
193 */
194 idBounds idRenderModelBeam::Bounds( const struct renderEntity_s *renderEntity ) const {
195         idBounds        b;
196
197         b.Zero();
198         if ( !renderEntity ) {
199                 b.ExpandSelf( 8.0f );
200         } else {
201                 idVec3  target = *reinterpret_cast<const idVec3 *>( &renderEntity->shaderParms[SHADERPARM_BEAM_END_X] );
202                 idVec3  localTarget;
203                 float   modelMatrix[16];
204                 R_AxisToModelMatrix( renderEntity->axis, renderEntity->origin, modelMatrix );
205                 R_GlobalPointToLocal( modelMatrix, target, localTarget ); 
206
207                 b.AddPoint( localTarget );
208                 if ( renderEntity->shaderParms[SHADERPARM_BEAM_WIDTH] != 0.0f ) {
209                         b.ExpandSelf( renderEntity->shaderParms[SHADERPARM_BEAM_WIDTH] * 0.5f );
210                 }
211         }
212         return b;
213 }