29 #include "../idlib/precompiled.h"
63 drawSurf->
geo = newTri;
75 static void R_AutospriteDeform(
drawSurf_t *surf ) {
88 common->
Warning(
"R_AutospriteDeform: shader had odd vertex count" );
92 common->
Warning(
"R_AutospriteDeform: autosprite had odd index count" );
112 for ( i = 0 ; i < tri->
numVerts ; i+=4 ) {
116 mid[0] = 0.25 * (v->
xyz[0] + (v+1)->xyz[0] + (v+2)->xyz[0] + (v+3)->xyz[0]);
117 mid[1] = 0.25 * (v->
xyz[1] + (v+1)->xyz[1] + (v+2)->xyz[1] + (v+3)->xyz[1]);
118 mid[2] = 0.25 * (v->
xyz[2] + (v+1)->xyz[2] + (v+2)->xyz[2] + (v+3)->xyz[2]);
120 delta = v->
xyz - mid;
121 radius = delta.
Length() * 0.707;
123 left = leftDir * radius;
126 ac[i+0].
xyz = mid + left + up;
129 ac[i+1].
xyz = mid - left + up;
132 ac[i+2].
xyz = mid - left - up;
135 ac[i+3].
xyz = mid + left - up;
139 newTri->
indexes[6*(i>>2)+0] = i;
140 newTri->
indexes[6*(i>>2)+1] = i+1;
141 newTri->
indexes[6*(i>>2)+2] = i+2;
143 newTri->
indexes[6*(i>>2)+3] = i;
144 newTri->
indexes[6*(i>>2)+4] = i+2;
145 newTri->
indexes[6*(i>>2)+5] = i+3;
148 R_FinishDeform( surf, newTri, ac );
163 static void R_TubeDeform(
drawSurf_t *surf ) {
167 static int edgeVerts[6][2] = {
179 common->
Error(
"R_AutospriteDeform: shader had odd vertex count" );
182 common->
Error(
"R_AutospriteDeform: autosprite had odd index count" );
204 for ( i = 0, indexes = 0 ; i < tri->
numVerts ; i+=4, indexes+=6 ) {
212 nums[0] = nums[1] = 0;
213 lengths[0] = lengths[1] = 999999;
215 for ( j = 0 ; j < 6 ; j++ ) {
221 l = ( v1->
xyz - v2->
xyz ).Length();
222 if ( l < lengths[0] ) {
224 lengths[1] = lengths[0];
227 }
else if ( l < lengths[1] ) {
235 for ( j = 0 ; j < 2 ; j++ ) {
239 mid[
j][0] = 0.5 * (v1->
xyz[0] + v2->
xyz[0]);
240 mid[
j][1] = 0.5 * (v1->
xyz[1] + v2->
xyz[1]);
241 mid[
j][2] = 0.5 * (v1->
xyz[2] + v2->
xyz[2]);
245 major = mid[1] - mid[0];
248 for ( j = 0 ; j < 2 ; j++ ) {
250 int i1 = tri->
indexes[i+edgeVerts[nums[
j]][0]];
251 int i2 = tri->
indexes[i+edgeVerts[nums[
j]][1]];
259 l = 0.5 * lengths[
j];
262 idVec3 dir = mid[
j] - localView;
263 minor.
Cross( major, dir );
267 av1->
xyz = mid[
j] - l * minor;
268 av2->
xyz = mid[
j] + l * minor;
270 av1->
xyz = mid[
j] + l * minor;
271 av2->
xyz = mid[
j] - l * minor;
276 R_FinishDeform( surf, newTri, ac );
285 #define MAX_TRI_WINDING_INDEXES 16
296 for ( i = 0 ; i < numTris ; i++ ) {
297 for ( j = 0 ; j < 3 ; j++ ) {
298 if ( tri->
indexes[i*3+j] != indexes[numIndexes-1] ) {
304 if ( numIndexes == 1 ) {
305 if ( next == indexes[0] ) {
309 for ( k = 1 ; k < numIndexes ; k++ ) {
310 if ( indexes[k] == next ) {
314 if ( k != numIndexes ) {
320 for ( k = 0 ; k < numTris ; k++ ) {
324 for ( l = 0 ; l < 3 ; l++ ) {
332 if ( b != indexes[numIndexes-1] ) {
343 if ( k != numTris ) {
348 indexes[numIndexes] =
next;
356 if ( numIndexes == tri->
numVerts ) {
359 }
while ( i != numTris );
509 static void R_FlareDeform(
drawSurf_t *surf ) {
539 float distFromPlane = localViewer * plane.
Normal() + plane[3];
540 if ( distFromPlane <= 0 ) {
548 for ( j = 1 ; j < tri->
numVerts ; j++ ) {
553 idVec3 dir = localViewer - center;
556 dot = dir * plane.
Normal();
563 for ( j = 0 ; j < newTri->
numVerts ; j++ ) {
577 if ( numIndexes != 4 ) {
582 for ( i = 0 ; i < 4 ; i++ ) {
590 idVec3 d1 = tri->
verts[ indexes[(i+1)%4] ].xyz - localViewer;
592 edgeDir[
i][1].
Cross( toEye, d1 );
596 idVec3 d2 = tri->
verts[ indexes[(i+3)%4] ].xyz - localViewer;
598 edgeDir[
i][0].Cross( toEye, d2 );
599 edgeDir[
i][0].Normalize();
601 edgeDir[
i][2] = edgeDir[
i][0] + edgeDir[
i][1];
602 edgeDir[
i][2].Normalize();
606 ac[4].
xyz = tri->
verts[ indexes[0] ].
xyz + spread * edgeDir[0][0];
610 ac[5].
xyz = tri->
verts[ indexes[0] ].
xyz + spread * edgeDir[0][2];
614 ac[6].
xyz = tri->
verts[ indexes[0] ].
xyz + spread * edgeDir[0][1];
619 ac[7].
xyz = tri->
verts[ indexes[1] ].
xyz + spread * edgeDir[1][0];
623 ac[8].
xyz = tri->
verts[ indexes[1] ].
xyz + spread * edgeDir[1][2];
627 ac[9].
xyz = tri->
verts[ indexes[1] ].
xyz + spread * edgeDir[1][1];
632 ac[10].
xyz = tri->
verts[ indexes[2] ].
xyz + spread * edgeDir[2][0];
636 ac[11].
xyz = tri->
verts[ indexes[2] ].
xyz + spread * edgeDir[2][2];
640 ac[12].
xyz = tri->
verts[ indexes[2] ].
xyz + spread * edgeDir[2][1];
645 ac[13].
xyz = tri->
verts[ indexes[3] ].
xyz + spread * edgeDir[3][0];
649 ac[14].
xyz = tri->
verts[ indexes[3] ].
xyz + spread * edgeDir[3][2];
653 ac[15].
xyz = tri->
verts[ indexes[3] ].
xyz + spread * edgeDir[3][1];
657 for ( i = 4 ; i < 16 ; i++ ) {
661 float ang = dir * plane.
Normal();
664 float newLen = -( distFromPlane / ang );
666 if ( newLen > 0 && newLen < len ) {
667 ac[
i].
xyz = localViewer + dir * newLen;
676 0,4,5, 0,5,6, 0,6,7, 0,7,1, 1,7,8, 1,8,9,
677 15,4,0, 15,0,3, 3,0,1, 3,1,2, 2,1,9, 2,9,10,
678 14,15,3, 14,3,13, 13,3,2, 13,2,12, 12,2,11, 11,2,10
683 0,1,2, 0,2,3, 0,4,5,0,5,6
687 memcpy( newTri->
indexes, triIndexes,
sizeof( triIndexes ) );
689 R_FinishDeform( surf, newTri, ac );
701 static void R_ExpandDeform(
drawSurf_t *surf ) {
718 for ( i = 0 ; i < tri->
numVerts ; i++ ) {
723 R_FinishDeform( surf, newTri, ac );
733 static void R_MoveDeform(
drawSurf_t *surf ) {
750 for ( i = 0 ; i < tri->
numVerts ; i++ ) {
752 ac[i].
xyz[0] += dist;
755 R_FinishDeform( surf, newTri, ac );
767 static void R_TurbulentDeform(
drawSurf_t *surf ) {
789 for ( i = 0 ; i < tri->
numVerts ; i++ ) {
792 f = timeOfs + domain *
f;
801 R_FinishDeform( surf, newTri, ac );
812 #define MAX_EYEBALL_TRIS 10
813 #define MAX_EYEBALL_ISLANDS 6
825 usedList[triangleNum] =
true;
835 a = tri->
indexes[triangleNum*3];
836 b = tri->
indexes[triangleNum*3+1];
837 c = tri->
indexes[triangleNum*3+2];
844 for (
int i = 0 ; i < numTri ; i++ ) {
856 || tri->
indexes[i*3+2] == c ) {
857 AddTriangleToIsland_r( tri, i, usedList, island );
870 static void R_EyeballDeform(
drawSurf_t *surf ) {
883 common->
Printf(
"R_EyeballDeform: too many triangles in surface" );
886 memset( triUsed, 0,
sizeof( triUsed ) );
889 islands[numIslands].
numTris = 0;
891 for ( i = 0 ; i < numTri ; i++ ) {
893 AddTriangleToIsland_r( tri, i, triUsed, &islands[numIslands] );
903 if ( numIslands != 3 ) {
904 common->
Printf(
"R_EyeballDeform: %i triangle islands\n", numIslands );
913 memset( newTri, 0,
sizeof( *newTri ) );
922 for ( i = 0 ; i < numIslands ; i++ ) {
926 for ( i = 0 ; i < numIslands ; i++ ) {
936 int originIsland = 0;
940 for ( j = 0 ; j < numIslands ; j++ ) {
944 for ( k = j-1 ; k >= 0 ; k-- ) {
945 if ( dist[k] > dist[k+1] ) {
946 int temp = sortOrder[k];
947 sortOrder[k] = sortOrder[k+1];
948 sortOrder[k+1] = temp;
949 float ftemp = dist[k];
956 originIsland = sortOrder[1];
957 origin = islands[originIsland].
mid;
959 focus = islands[sortOrder[2]].
mid;
962 idVec3 dir = focus - origin;
977 texVec[0].
Cross( v1, v2 );
979 texVec[1].
Cross( texVec[0], dir );
981 for ( j = 0 ; j < 2 ; j++ ) {
982 texVec[
j] -= dir * ( texVec[
j] * dir );
988 for ( j = 0 ; j < islands[
i].
numTris ; j++ ) {
989 for ( k = 0 ; k < 3 ; k++ ) {
999 ac[
index].
st[0] = 0.5 + local * texVec[0];
1000 ac[
index].
st[1] = 0.5 + local * texVec[1];
1005 R_FinishDeform( surf, newTri, ac );
1018 static void R_ParticleDeform(
drawSurf_t *surf,
bool useArea ) {
1039 float totalArea = 0;
1040 float *sourceTriAreas =
NULL;
1044 sourceTriAreas = (
float *)_alloca(
sizeof( *sourceTriAreas ) * numSourceTris );
1046 for (
int i = 0 ; i < srcTri->
numIndexes ; i += 3, triNum++ ) {
1049 sourceTriAreas[triNum] = totalArea;
1064 for (
int currentTri = 0; currentTri < ( ( useArea ) ? 1 : numSourceTris ); currentTri++ ) {
1066 for (
int stageNum = 0 ; stageNum < particleSystem->
stages.
Num() ; stageNum++ ) {
1099 idRandom steppingRandom, steppingRandom2;
1102 int stageCycle = stageAge / stage->
cycleMsec;
1103 int inCycleTime = stageAge - stageCycle * stage->
cycleMsec;
1119 int particleAge = stageAge - bunchOffset;
1120 int particleCycle = particleAge / stage->
cycleMsec;
1121 if ( particleCycle < 0 ) {
1125 if ( stage->
cycles && particleCycle >= stage->
cycles ) {
1130 if ( particleCycle == stageCycle ) {
1131 g.
random = steppingRandom;
1133 g.
random = steppingRandom2;
1136 int inCycleTime = particleAge - particleCycle * stage->
cycleMsec;
1150 if ( g.
frac > 1.0 ) {
1159 int pointTri = currentTri;
1163 pointTri = idBinSearch_LessEqual<float>( sourceTriAreas, numSourceTris, g.
random.
RandomFloat() * totalArea );
1175 float ft = 1.0f / ( f1 + f2 + f3 + 0.0001f );
1201 for (
int i = 0 ; i < tri->
numVerts ; i += 4 ) {
1203 tri->
indexes[indexes+1] = i+2;
1204 tri->
indexes[indexes+2] = i+3;
1206 tri->
indexes[indexes+4] = i+3;
1207 tri->
indexes[indexes+5] = i+1;
1240 R_AutospriteDeform( drawSurf );
1243 R_TubeDeform( drawSurf );
1246 R_FlareDeform( drawSurf );
1249 R_ExpandDeform( drawSurf );
1252 R_MoveDeform( drawSurf );
1255 R_TurbulentDeform( drawSurf );
1258 R_EyeballDeform( drawSurf );
1261 R_ParticleDeform( drawSurf,
true );
1264 R_ParticleDeform( drawSurf,
false );
idCVar r_skipParticles("r_skipParticles","0", CVAR_RENDERER|CVAR_INTEGER,"1 = skip all particle systems", 0, 1, idCmdSystem::ArgCompletion_Integer< 0, 1 >)
const srfTriangles_t * geo
bool FromPoints(const idVec3 &p1, const idVec3 &p2, const idVec3 &p3, bool fixDegenerate=true)
const idVec3 & Normal(void) const
const int SHADERPARM_DIVERSITY
idMat3 mat3_identity(idVec3(1, 0, 0), idVec3(0, 1, 0), idVec3(0, 0, 1))
idVec3 GetCenter(void) const
void R_AddDrawSurf(const srfTriangles_t *tri, const viewEntity_t *space, const renderEntity_t *renderEntity, const idMaterial *shader, const idScreenRect &scissor)
bool ReceivesLighting(void) const
float GetFloat(void) const
GLenum GLsizei GLenum GLenum const GLvoid * table
deform_t Deform(void) const
const renderEntity_t * renderEnt
int tris[MAX_EYEBALL_TRIS]
static const int MAX_RAND
void R_DeriveTangents(srfTriangles_t *tri, bool allocFacePlanes=true)
idVec3 Cross(const idVec3 &a) const
const struct viewEntity_s * space
struct vertCache_s * ambientCache
const idMaterial * material
void * R_ClearedFrameAlloc(int bytes)
bool AddPoint(const idVec3 &v)
GLfloat GLfloat GLfloat v2
GLuint GLuint GLsizei count
idVec3 vec3_origin(0.0f, 0.0f, 0.0f)
static float TriangleArea(const idVec3 &a, const idVec3 &b, const idVec3 &c)
virtual int CreateParticle(particleGen_t *g, idDrawVert *verts) const
const renderView_t * renderView
idCVar r_flareSize("r_flareSize","1", CVAR_RENDERER|CVAR_FLOAT,"scale the flare deforms from the material def")
const struct portalStack_s * next
const idMaterial * material
void R_GlobalVectorToLocal(const float modelMatrix[16], const idVec3 &in, idVec3 &out)
idRenderEntityLocal * entityDef
const int SHADERPARM_TIMEOFFSET
GLubyte GLubyte GLubyte a
virtual void Printf(const char *fmt,...) id_attribute((format(printf
idList< idParticleStage * > stages
vertCache_t * AllocFrameTemp(void *data, int bytes)
void R_GlobalPointToLocal(const float modelMatrix[16], const idVec3 &in, idVec3 &out)
GLfloat GLfloat GLfloat GLfloat v3
idCVar r_skipDeforms("r_skipDeforms","0", CVAR_RENDERER|CVAR_BOOL,"leave all deform materials in their original state")
const int GetDeformRegister(int index) const
void * R_FrameAlloc(int bytes)
idVertexCache vertexCache
const idDecl * GetDeformDecl(void) const
float dot(float a[], float b[])
virtual void Error(const char *fmt,...) id_attribute((format(printf
virtual void virtual void Warning(const char *fmt,...) id_attribute((format(printf
float shaderParms[MAX_ENTITY_SHADER_PARMS]
const float * shaderRegisters
virtual int NumQuadsPerParticle() const
const int SHADERPARM_PARTICLE_STOPTIME
float TableLookup(float index) const