/* ================= idRenderModelDecal::AddWinding ================= */ void idRenderModelDecal::AddWinding( const idWinding &w, const idMaterial *decalMaterial, const idPlane fadePlanes[2], float fadeDepth, int startTime ) { int i; float invFadeDepth, fade; decalInfo_t decalInfo; if ( ( material == NULL || material == decalMaterial ) && tri.numVerts + w.GetNumPoints() < MAX_DECAL_VERTS && tri.numIndexes + ( w.GetNumPoints() - 2 ) * 3 < MAX_DECAL_INDEXES ) { material = decalMaterial; // add to this decal decalInfo = material->GetDecalInfo(); invFadeDepth = -1.0f / fadeDepth; for ( i = 0; i < w.GetNumPoints(); i++ ) { fade = fadePlanes[0].Distance( w[i].ToVec3() ) * invFadeDepth; if ( fade < 0.0f ) { fade = fadePlanes[1].Distance( w[i].ToVec3() ) * invFadeDepth; } if ( fade < 0.0f ) { fade = 0.0f; } else if ( fade > 0.99f ) { fade = 1.0f; } fade = 1.0f - fade; vertDepthFade[tri.numVerts + i] = fade; tri.verts[tri.numVerts + i].xyz = w[i].ToVec3(); tri.verts[tri.numVerts + i].st[0] = w[i].s; tri.verts[tri.numVerts + i].st[1] = w[i].t; for ( int k = 0 ; k < 4 ; k++ ) { int icolor = idMath::FtoiFast( decalInfo.start[k] * fade * 255.0f ); if ( icolor < 0 ) { icolor = 0; } else if ( icolor > 255 ) { icolor = 255; } tri.verts[tri.numVerts + i].color[k] = icolor; } } for ( i = 2; i < w.GetNumPoints(); i++ ) { tri.indexes[tri.numIndexes + 0] = tri.numVerts; tri.indexes[tri.numIndexes + 1] = tri.numVerts + i - 1; tri.indexes[tri.numIndexes + 2] = tri.numVerts + i; indexStartTime[tri.numIndexes] = indexStartTime[tri.numIndexes + 1] = indexStartTime[tri.numIndexes + 2] = startTime; tri.numIndexes += 3; } tri.numVerts += w.GetNumPoints(); return; } // if we are at the end of the list, create a new decal if ( !nextDecal ) { nextDecal = idRenderModelDecal::Alloc(); } // let the next decal on the chain take a look nextDecal->AddWinding( w, decalMaterial, fadePlanes, fadeDepth, startTime ); }
/* ============ idBrush::FromWinding ============ */ bool idBrush::FromWinding( const idWinding& w, const idPlane& windingPlane ) { int i, j, bestAxis; idPlane plane; idVec3 normal, axialNormal; sides.Append( new idBrushSide( windingPlane, -1 ) ); sides.Append( new idBrushSide( -windingPlane, -1 ) ); bestAxis = 0; for( i = 1; i < 3; i++ ) { if( idMath::Fabs( windingPlane.Normal()[i] ) > idMath::Fabs( windingPlane.Normal()[bestAxis] ) ) { bestAxis = i; } } axialNormal = vec3_origin; if( windingPlane.Normal()[bestAxis] > 0.0f ) { axialNormal[bestAxis] = 1.0f; } else { axialNormal[bestAxis] = -1.0f; } for( i = 0; i < w.GetNumPoints(); i++ ) { j = ( i + 1 ) % w.GetNumPoints(); normal = ( w[j].ToVec3() - w[i].ToVec3() ).Cross( axialNormal ); if( normal.Normalize() < 0.5f ) { continue; } plane.SetNormal( normal ); plane.FitThroughPoint( w[j].ToVec3() ); sides.Append( new idBrushSide( plane, -1 ) ); } if( sides.Num() < 4 ) { for( i = 0; i < sides.Num(); i++ ) { delete sides[i]; } sides.Clear(); return false; } sides[0]->winding = w.Copy(); windingsValid = true; BoundBrush(); return true; }
/* ============ idTraceModel::SetupPolygon ============ */ void idTraceModel::SetupPolygon( const idWinding &w ) { int i; idVec3 *verts; verts = (idVec3 *) _alloca16( w.GetNumPoints() * sizeof( idVec3 ) ); for ( i = 0; i < w.GetNumPoints(); i++ ) { verts[i] = w[i].ToVec3(); } SetupPolygon( verts, w.GetNumPoints() ); }
void idSaveGame::WriteWinding( const idWinding &w ) { int i, num; num = w.GetNumPoints(); WriteInt( num ); for( i = 0; i < num; i++ ) { WriteVec5( w[i] ); } }
/* ================ idRestoreGame::ReadWinding ================ */ void idRestoreGame::ReadWinding( idWinding &w ) { int i, num; file->ReadInt( num ); w.SetNumPoints( num ); for( i = 0; i < num; i++ ) { file->Read( &w[i], sizeof( idVec5 ) ); LittleRevBytes( &w[i], sizeof( float ), sizeof( idVec5 ) / sizeof( float ) ); } }
/* ================ idSaveGame::WriteBounds ================ */ void idSaveGame::WriteWinding( const idWinding &w ) { int i, num; num = w.GetNumPoints(); file->WriteInt( num ); for( i = 0; i < num; i++ ) { idVec5 v = w[i]; LittleRevBytes( &v, sizeof( float ), sizeof( v ) / sizeof( float ) ); file->Write( &v, sizeof( v ) ); } }
/* ================ idSaveGame::WriteBounds ================ */ void idSaveGame::WriteWinding( const idWinding& w ) { int i, num; num = w.GetNumPoints(); file->WriteBig( num ); for( i = 0; i < num; i++ ) { idVec5 v = w[i]; file->WriteBig( v ); } }
/* ================ idRestoreGame::ReadWinding ================ */ void idRestoreGame::ReadWinding( idWinding& w ) { int i, num; ReadInt( num ); w.SetNumPoints( num ); for( i = 0; i < num; i++ ) { idVec5& v = w[i]; file->ReadBig( v ); } }
void idRestoreGame::ReadWinding( idWinding &w ) { int i, num; ReadInt( num ); if( num < 0 ) { Error( "idRestoreGame::ReadWinding: negative number of points (%d)", num ); } w.SetNumPoints( num ); for( i = 0; i < num; i++ ) { ReadVec5( w[i] ); } }
/* ================= idRenderModelDecal::CreateDecalFromWinding ================= */ void idRenderModelDecal::CreateDecalFromWinding( const idWinding &w, const idMaterial *decalMaterial, const idPlane fadePlanes[2], float fadeDepth, int startTime ) { // Often we are appending a new triangle to an existing decal, so merge with the previous decal if possible int decalIndex = ( nextDecal - 1 ) & ( MAX_DECALS - 1 ); if ( decalIndex >= 0 && decals[decalIndex].material == decalMaterial && decals[decalIndex].startTime == startTime && decals[decalIndex].numVerts + w.GetNumPoints() <= MAX_DECAL_VERTS && decals[decalIndex].numIndexes + 3 * ( w.GetNumPoints() - 2 ) <= MAX_DECAL_INDEXES ) { } else { decalIndex = nextDecal++ & ( MAX_DECALS - 1 ); decals[decalIndex].material = decalMaterial; decals[decalIndex].startTime = startTime; decals[decalIndex].numVerts = 0; decals[decalIndex].numIndexes = 0; assert( w.GetNumPoints() <= MAX_DECAL_VERTS ); if ( nextDecal - firstDecal > MAX_DECALS ) { firstDecal = nextDecal - MAX_DECALS; } } decal_t & decal = decals[decalIndex]; const float invFadeDepth = -1.0f / fadeDepth; int firstVert = decal.numVerts; // create the vertices for ( int i = 0; i < w.GetNumPoints(); i++ ) { float depthFade = fadePlanes[0].Distance( w[i].ToVec3() ) * invFadeDepth; if ( depthFade < 0.0f ) { depthFade = fadePlanes[1].Distance( w[i].ToVec3() ) * invFadeDepth; } if ( depthFade < 0.0f ) { depthFade = 0.0f; } else if ( depthFade > 0.99f ) { depthFade = 1.0f; } decal.vertDepthFade[decal.numVerts] = 1.0f - depthFade; decal.verts[decal.numVerts].Clear(); decal.verts[decal.numVerts].xyz = w[i].ToVec3(); decal.verts[decal.numVerts].SetTexCoord( w[i].s, w[i].t ); decal.numVerts++; } // create the indexes for ( int i = 2; i < w.GetNumPoints(); i++ ) { assert( decal.numIndexes + 3 <= MAX_DECAL_INDEXES ); decal.indexes[decal.numIndexes + 0] = firstVert; decal.indexes[decal.numIndexes + 1] = firstVert + i - 1; decal.indexes[decal.numIndexes + 2] = firstVert + i; decal.numIndexes += 3; } // add degenerate triangles until the index size is a multiple of 16 bytes for ( ; ( ( ( decal.numIndexes * sizeof( triIndex_t ) ) & 15 ) != 0 ); decal.numIndexes += 3 ) { assert( decal.numIndexes + 3 <= MAX_DECAL_INDEXES ); decal.indexes[decal.numIndexes + 0] = 0; decal.indexes[decal.numIndexes + 1] = 0; decal.indexes[decal.numIndexes + 2] = 0; } }