/* ================ idBrittleFracture::CreateFractures ================ */ void idBrittleFracture::CreateFractures( const idRenderModel* renderModel ) { if( !renderModel || renderModel->NumSurfaces() < 1 ) { return; } physicsObj.SetSelf( this ); physicsObj.SetOrigin( GetPhysics()->GetOrigin(), 0 ); physicsObj.SetAxis( GetPhysics()->GetAxis(), 0 ); const modelSurface_t* surf = renderModel->Surface( 0 ); material = surf->shader; idMat3 physAxis; physAxis = physicsObj.GetAxis(); if( isXraySurface ) { idFixedWinding w; for( int i = 0; i < 4; i++ ) { const idDrawVert* v = &surf->geometry->verts[i]; w.AddPoint( idVec5( v->xyz, v->GetTexCoord() ) ); } idRandom2 random( entityNumber ); Fracture_r( w , random ); } else { const idDrawVert* verts = surf->geometry->verts; triIndex_t* indexes = surf->geometry->indexes; for( int j = 0; j < surf->geometry->numIndexes; j += 3 ) { int i0 = indexes[ j + 0 ]; int i1 = indexes[ j + 1 ]; int i2 = indexes[ j + 2 ]; idFixedWinding w; w.AddPoint( idVec5( verts[i2].xyz, verts[i2].GetTexCoord() ) ); w.AddPoint( idVec5( verts[i1].xyz, verts[i1].GetTexCoord() ) ); w.AddPoint( idVec5( verts[i0].xyz, verts[i0].GetTexCoord() ) ); idPlane p1; w.GetPlane( p1 ); for( int k = j + 3; k < surf->geometry->numIndexes && ( w.GetNumPoints() + 1 < MAX_POINTS_ON_WINDING ); k += 3 ) { int i3 = indexes[ k + 0 ]; int i4 = indexes[ k + 1 ]; int i5 = indexes[ k + 2 ]; idFixedWinding w2; w2.AddPoint( idVec5( verts[i5].xyz, verts[i5].GetTexCoord() ) ); w2.AddPoint( idVec5( verts[i4].xyz, verts[i4].GetTexCoord() ) ); w2.AddPoint( idVec5( verts[i3].xyz, verts[i3].GetTexCoord() ) ); idPlane p2; w2.GetPlane( p2 ); if( p1 != p2 ) { break; } bool found = false; for( int w1i = 0; w1i < w.GetNumPoints(); w1i++ ) { for( int w2i = 0; w2i < w2.GetNumPoints(); w2i++ ) { if( CompareVec5( w[w1i], w2[w2i] ) && CompareVec5( w[( w1i + 1 ) % w.GetNumPoints()], w2[( w2i + 2 ) % w2.GetNumPoints()] ) ) { w.InsertPoint( w2[( w2i + 1 ) % w2.GetNumPoints()], ( w1i + 1 ) % w.GetNumPoints() ); j = k; found = true; break; } } if( found ) { break; } } if( !found ) { break; } } idRandom2 random( entityNumber ); Fracture_r( w, random ); } } physicsObj.SetContents( material->GetContentFlags() ); SetPhysics( &physicsObj ); }
/* ============= DrawStretchPic ============= */ void idGuiModel::DrawStretchPic( const idDrawVert *dverts, const glIndex_t *dindexes, int vertCount, int indexCount, const idMaterial *hShader, bool clip, float min_x, float min_y, float max_x, float max_y ) { if ( !glConfig.isInitialized ) { return; } if ( !( dverts && dindexes && vertCount && indexCount && hShader ) ) { return; } // break the current surface if we are changing to a new material if ( hShader != surf->material ) { if ( surf->numVerts ) { AdvanceSurf(); } const_cast<idMaterial *>(hShader)->EnsureNotPurged(); // in case it was a gui item started before a level change surf->material = hShader; } // add the verts and indexes to the current surface if ( clip ) { int i, j; // FIXME: this is grim stuff, and should be rewritten if we have any significant // number of guis asking for clipping idFixedWinding w; for ( i = 0; i < indexCount; i += 3 ) { w.Clear(); w.AddPoint(idVec5(dverts[dindexes[i]].xyz.x, dverts[dindexes[i]].xyz.y, dverts[dindexes[i]].xyz.z, dverts[dindexes[i]].st.x, dverts[dindexes[i]].st.y)); w.AddPoint(idVec5(dverts[dindexes[i+1]].xyz.x, dverts[dindexes[i+1]].xyz.y, dverts[dindexes[i+1]].xyz.z, dverts[dindexes[i+1]].st.x, dverts[dindexes[i+1]].st.y)); w.AddPoint(idVec5(dverts[dindexes[i+2]].xyz.x, dverts[dindexes[i+2]].xyz.y, dverts[dindexes[i+2]].xyz.z, dverts[dindexes[i+2]].st.x, dverts[dindexes[i+2]].st.y)); for ( j = 0; j < 3; j++ ) { if ( w[j].x < min_x || w[j].x > max_x || w[j].y < min_y || w[j].y > max_y ) { break; } } if ( j < 3 ) { idPlane p; p.Normal().y = p.Normal().z = 0.0f; p.Normal().x = 1.0f; p.SetDist( min_x ); w.ClipInPlace( p ); p.Normal().y = p.Normal().z = 0.0f; p.Normal().x = -1.0f; p.SetDist( -max_x ); w.ClipInPlace( p ); p.Normal().x = p.Normal().z = 0.0f; p.Normal().y = 1.0f; p.SetDist( min_y ); w.ClipInPlace( p ); p.Normal().x = p.Normal().z = 0.0f; p.Normal().y = -1.0f; p.SetDist( -max_y ); w.ClipInPlace( p ); } int numVerts = verts.Num(); verts.SetNum( numVerts + w.GetNumPoints(), false ); for ( j = 0 ; j < w.GetNumPoints() ; j++ ) { idDrawVert *dv = &verts[numVerts+j]; dv->xyz.x = w[j].x; dv->xyz.y = w[j].y; dv->xyz.z = w[j].z; dv->st.x = w[j].s; dv->st.y = w[j].t; dv->normal.Set(0, 0, 1); dv->tangents[0].Set(1, 0, 0); dv->tangents[1].Set(0, 1, 0); } surf->numVerts += w.GetNumPoints(); for ( j = 2; j < w.GetNumPoints(); j++ ) { indexes.Append( numVerts - surf->firstVert ); indexes.Append( numVerts + j - 1 - surf->firstVert ); indexes.Append( numVerts + j - surf->firstVert ); surf->numIndexes += 3; } } } else { int numVerts = verts.Num(); int numIndexes = indexes.Num(); verts.AssureSize( numVerts + vertCount ); indexes.AssureSize( numIndexes + indexCount ); surf->numVerts += vertCount; surf->numIndexes += indexCount; for ( int i = 0; i < indexCount; i++ ) { indexes[numIndexes + i] = numVerts + dindexes[i] - surf->firstVert; } memcpy( &verts[numVerts], dverts, vertCount * sizeof( verts[0] ) ); } }
/* ============== sdDeployMaskEditSession::UpdateProjection ============== */ void sdDeployMaskEditSession::UpdateProjection( const idVec3& position ) { if ( !decalMaterial ) { return; } if ( decalHandle == -1 ) { decalHandle = gameLocal.RegisterLoggedDecal( decalMaterial ); } gameLocal.ResetLoggedDecal( decalHandle ); gameDecalInfo_t* decalInfo = gameLocal.GetLoggedDecal( decalHandle ); sdDeployMaskInstance* mask = GetMask( position ); const sdHeightMapInstance* heightMap = GetHeightMap( position ); if ( mask != NULL && mask->IsValid() && heightMap != NULL ) { sdDeployMask::extents_t extents; GetExtents( position, *mask, extents ); float depth = 512.0f; int maxX, maxY; mask->GetDimensions( maxX, maxY ); sdDeployMask::extents_t expandedExtents; expandedExtents.minx = Max( 0, extents.minx - 2 ); expandedExtents.miny = Max( 0, extents.miny - 2 ); expandedExtents.maxx = Min( maxX, extents.maxx + 2 ); expandedExtents.maxy = Min( maxY, extents.maxy + 2 ); idList< const idMaterial* > megaTextureMaterials; const idStrList& megaTextureMaterialNames = gameLocal.GetMapInfo().GetMegatextureMaterials(); for ( int i = 0; i < megaTextureMaterialNames.Num(); i++ ) { megaTextureMaterials.Append( declHolder.FindMaterial( megaTextureMaterialNames[ i ] ) ); } idFixedWinding winding; int spawnID = WORLD_SPAWN_ID; for ( int i = expandedExtents.minx; i <= expandedExtents.maxx; i++ ) { for ( int j = expandedExtents.miny; j <= expandedExtents.maxy; j++ ) { gameDecalInfo_t* info = decalInfo; if ( !info ) { continue; } sdDeployMask::extents_t localExtents; localExtents.minx = i; localExtents.maxx = i; localExtents.miny = j; localExtents.maxy = j; idBounds bounds; mask->GetBounds( localExtents, bounds, heightMap ); idVec3 top = bounds.GetCenter(); top[ 2 ] = bounds.GetMaxs()[ 2 ]; deployResult_t localResult = mask->IsValid( localExtents ); idVec4 localColor; switch ( localResult ) { case DR_CLEAR: localColor = colorGreen; break; default: case DR_FAILED: localColor = colorDkRed; break; } if ( !( ( i >= extents.minx ) && ( i <= extents.maxx ) && ( j >= extents.miny ) && ( j <= extents.maxy ) ) ) { localColor.x *= 0.3f; localColor.y *= 0.3f; localColor.z *= 0.3f; } winding.Clear(); winding += idVec5( idVec3( bounds.GetMins()[ 0 ], bounds.GetMins()[ 1 ], bounds.GetMins()[ 2 ] - depth ), idVec2( 0.0f, 0.0f ) ); winding += idVec5( idVec3( bounds.GetMins()[ 0 ], bounds.GetMaxs()[ 1 ], bounds.GetMins()[ 2 ] - depth ), idVec2( 0.0f, 1.0f ) ); winding += idVec5( idVec3( bounds.GetMaxs()[ 0 ], bounds.GetMaxs()[ 1 ], bounds.GetMins()[ 2 ] - depth ), idVec2( 1.0f, 1.0f ) ); winding += idVec5( idVec3( bounds.GetMaxs()[ 0 ], bounds.GetMins()[ 1 ], bounds.GetMins()[ 2 ] - depth ), idVec2( 1.0f, 0.0f ) ); gameRenderWorld->AddToProjectedDecal( winding, top + idVec3( 0, 0, 64.f + depth ), true, localColor, info->renderEntity.hModel, spawnID, megaTextureMaterials.Begin(), megaTextureMaterials.Num() ); } } } }
/* ============== sdDeployMenu::Update ============== */ void sdDeployMenu::Update( void ) { sdHudModule::Update(); idPlayer* localPlayer = gameLocal.GetLocalPlayer(); if ( !deployableObject || !localPlayer ) { return; } deployResult_t result = localPlayer->GetDeployResult( position, deployableObject ); if ( result != DR_OUT_OF_RANGE ) { if ( deployableRenderEntityHandle < 0 ) { deployableRenderEntityHandle = gameRenderWorld->AddEntityDef( &deployableRenderEntity ); } idVec4 color; switch ( deployableState ) { case DR_CLEAR: color = colorGreen; break; case DR_WARNING: color = colorOrange; break; case DR_CONDITION_FAILED: color = colorWhite; break; default: case DR_FAILED: color = colorDkRed; break; } if ( decalHandle == -1 ) { decalHandle = gameLocal.RegisterLoggedDecal( decalMaterial ); lastExpandedExtents.minx = -1; } if ( decalHandleOuter == -1 ) { decalHandleOuter = gameLocal.RegisterLoggedDecal( decalMaterialOuter ); lastExpandedExtents.minx = -1; } if ( decalHandleArrows == -1 ) { decalHandleArrows = gameLocal.RegisterLoggedDecal( decalMaterialArrows ); } gameLocal.ResetLoggedDecal( decalHandleArrows ); gameDecalInfo_t* decalInfo = gameLocal.GetLoggedDecal( decalHandle ); gameDecalInfo_t* decalInfoOuter = gameLocal.GetLoggedDecal( decalHandleOuter ); gameDecalInfo_t* decalInfoArrows = gameLocal.GetLoggedDecal( decalHandleArrows ); if ( !deployableObject->AllowRotation() ) { rotation = 0.0f; } idMat3 rotationStart; idAngles::YawToMat3( rotation, rotationStart ); const sdPlayZone* playZone = gameLocal.GetPlayZone( position, sdPlayZone::PZF_DEPLOYMENT ); const sdPlayZone* playZoneHeight = gameLocal.GetPlayZone( position, sdPlayZone::PZF_HEIGHTMAP ); const sdHeightMapInstance* heightMap = NULL; if ( playZoneHeight ) { heightMap = &playZoneHeight->GetHeightMap(); } const sdDeployMaskInstance* mask = NULL; if ( playZone ) { mask = playZone->GetMask( deployableObject->GetDeploymentMask() ); } if ( mask && mask->IsValid() && heightMap && heightMap->IsValid() ) { idBounds bounds( position ); bounds.ExpandSelf( deployableObject->GetObjectSize() ); sdDeployMask::extents_t extents; mask->CoordsForBounds( bounds, extents ); idBounds mainBounds; mask->GetBounds( extents, mainBounds, heightMap ); float depth = 512.0f; idVec3 top; idBounds moveArrowBounds = mainBounds; idBounds rotateArrowBounds = mainBounds; // straight arrows moveArrowBounds.GetMaxs().y = moveArrowBounds.GetCenter().y; moveArrowBounds.GetMins().y += 0.25f * ( mainBounds.GetMaxs().y - mainBounds.GetMins().y ); moveArrowBounds.GetMaxs().y += 0.25f * ( mainBounds.GetMaxs().y - mainBounds.GetMins().y ); moveArrowBounds.GetMins().x = moveArrowBounds.GetCenter().x; { idVec3 center = moveArrowBounds.GetCenter(); moveArrowBounds.TranslateSelf( -center ); for ( int index = 0; index < 3; index++ ) { moveArrowBounds.GetMins()[ index ] *= 0.25f; moveArrowBounds.GetMaxs()[ index ] *= 0.25f; } moveArrowBounds.TranslateSelf( center ); } // rotate arrows rotateArrowBounds.GetMins().x = rotateArrowBounds.GetCenter().x; { idVec3 center = rotateArrowBounds.GetCenter(); rotateArrowBounds.TranslateSelf( -center ); for ( int index = 0; index < 3; index++ ) { rotateArrowBounds.GetMins()[ index ] *= 0.2f; rotateArrowBounds.GetMaxs()[ index ] *= 0.2f; } rotateArrowBounds.TranslateSelf( center ); } top = mainBounds.GetCenter(); top[ 2 ] = mainBounds.GetMaxs()[ 2 ]; idList< const idMaterial* > megaTextureMaterials; const idStrList& megaTextureMaterialNames = gameLocal.GetMapInfo().GetMegatextureMaterials(); for ( int i = 0; i < megaTextureMaterialNames.Num(); i++ ) { megaTextureMaterials.Append( declHolder.FindMaterial( megaTextureMaterialNames[ i ] ) ); } idFixedWinding winding; int spawnID = WORLD_SPAWN_ID; if ( GetDeployMode() ) { // rotate mode idMat3 rotationOffset; idAngles::YawToMat3( 120.0f, rotationOffset ); // forward arrow winding += idVec5( idVec3( moveArrowBounds.GetMins().x, moveArrowBounds.GetMins().y, moveArrowBounds.GetMins().z - depth ), idVec2( 0.5f, 0.0f ) ); winding += idVec5( idVec3( moveArrowBounds.GetMins().x, moveArrowBounds.GetMaxs().y, moveArrowBounds.GetMins().z - depth ), idVec2( 0.5f, 0.5f ) ); winding += idVec5( idVec3( moveArrowBounds.GetMaxs().x, moveArrowBounds.GetMaxs().y, moveArrowBounds.GetMins().z - depth ), idVec2( 1.0f, 0.5f ) ); winding += idVec5( idVec3( moveArrowBounds.GetMaxs().x, moveArrowBounds.GetMins().y, moveArrowBounds.GetMins().z - depth ), idVec2( 1.0f, 0.0f ) ); winding.Rotate( mainBounds.GetCenter(), rotationStart ); idVec3 offset = rotationStart[ 0 ] * ( 16.f * idMath::Sin( ( gameLocal.time / 500.f ) ) ); for ( int i = 0; i < winding.GetNumPoints(); i++ ) { winding[ i ].ToVec3() += offset; } gameRenderWorld->AddToProjectedDecal( winding, top + idVec3( 0.0f, 0.0f, 64.0f + depth ), true, idVec4( 0.87f, 0.59f, 0.f, 1.f ), decalInfoArrows->renderEntity.hModel, spawnID, megaTextureMaterials.Begin(), megaTextureMaterials.Num() ); // rotate arrows winding.Clear(); winding += idVec5( idVec3( rotateArrowBounds.GetMins().x, rotateArrowBounds.GetMins().y, rotateArrowBounds.GetMins().z - depth ), idVec2( 0.0f, 0.0f ) ); winding += idVec5( idVec3( rotateArrowBounds.GetMins().x, rotateArrowBounds.GetMaxs().y, rotateArrowBounds.GetMins().z - depth ), idVec2( 0.0f, 1.0f ) ); winding += idVec5( idVec3( rotateArrowBounds.GetMaxs().x, rotateArrowBounds.GetMaxs().y, rotateArrowBounds.GetMins().z - depth ), idVec2( 0.5f, 1.0f ) ); winding += idVec5( idVec3( rotateArrowBounds.GetMaxs().x, rotateArrowBounds.GetMins().y, rotateArrowBounds.GetMins().z - depth ), idVec2( 0.5f, 0.0f ) ); winding.Rotate( mainBounds.GetCenter(), rotationStart * rotationOffset ); gameRenderWorld->AddToProjectedDecal( winding, top + idVec3( 0.0f, 0.0f, 64.0f + depth ), true, colorWhite, decalInfoArrows->renderEntity.hModel, spawnID, megaTextureMaterials.Begin(), megaTextureMaterials.Num() ); winding.Rotate( mainBounds.GetCenter(), rotationOffset ); gameRenderWorld->AddToProjectedDecal( winding, top + idVec3( 0.0f, 0.0f, 64.0f + depth ), true, colorWhite, decalInfoArrows->renderEntity.hModel, spawnID, megaTextureMaterials.Begin(), megaTextureMaterials.Num() ); } else { // move mode idMat3 rotationOffset; idAngles::YawToMat3( 90.0f, rotationOffset ); winding += idVec5( idVec3( moveArrowBounds.GetMins().x, moveArrowBounds.GetMins().y, moveArrowBounds.GetMins().z - depth ), idVec2( 0.5f, 0.0f ) ); winding += idVec5( idVec3( moveArrowBounds.GetMins().x, moveArrowBounds.GetMaxs().y, moveArrowBounds.GetMins().z - depth ), idVec2( 0.5f, 0.5f ) ); winding += idVec5( idVec3( moveArrowBounds.GetMaxs().x, moveArrowBounds.GetMaxs().y, moveArrowBounds.GetMins().z - depth ), idVec2( 1.0f, 0.5f ) ); winding += idVec5( idVec3( moveArrowBounds.GetMaxs().x, moveArrowBounds.GetMins().y, moveArrowBounds.GetMins().z - depth ), idVec2( 1.0f, 0.0f ) ); gameRenderWorld->AddToProjectedDecal( winding, top + idVec3( 0.0f, 0.0f, 64.0f + depth ), true, colorWhite, decalInfoArrows->renderEntity.hModel, spawnID, megaTextureMaterials.Begin(), megaTextureMaterials.Num() ); winding.Rotate( mainBounds.GetCenter(), rotationOffset ); gameRenderWorld->AddToProjectedDecal( winding, top + idVec3( 0.0f, 0.0f, 64.0f + depth ), true, colorWhite, decalInfoArrows->renderEntity.hModel, spawnID, megaTextureMaterials.Begin(), megaTextureMaterials.Num() ); winding.Rotate( mainBounds.GetCenter(), rotationOffset ); gameRenderWorld->AddToProjectedDecal( winding, top + idVec3( 0.0f, 0.0f, 64.0f + depth ), true, colorWhite, decalInfoArrows->renderEntity.hModel, spawnID, megaTextureMaterials.Begin(), megaTextureMaterials.Num() ); winding.Rotate( mainBounds.GetCenter(), rotationOffset ); gameRenderWorld->AddToProjectedDecal( winding, top + idVec3( 0.0f, 0.0f, 64.0f + depth ), true, colorWhite, decalInfoArrows->renderEntity.hModel, spawnID, megaTextureMaterials.Begin(), megaTextureMaterials.Num() ); } // the grid int maxX, maxY; mask->GetDimensions( maxX, maxY ); sdDeployMask::extents_t expandedExtents; expandedExtents.minx = Max( 0, extents.minx - 2 ); expandedExtents.miny = Max( 0, extents.miny - 2 ); expandedExtents.maxx = Min( maxX, extents.maxx + 2 ); expandedExtents.maxy = Min( maxY, extents.maxy + 2 ); int w = expandedExtents.maxx - expandedExtents.minx + 1; int h = expandedExtents.maxx - expandedExtents.minx + 1; int terrIdx = 0; bool regen = false; if ( ( w * h ) > sizeof( lastTerritory ) / sizeof( lastTerritory[0] ) ) { common->Warning( "test territory size too large" ); return; } for ( int i = expandedExtents.minx; i <= expandedExtents.maxx; i++ ) { for ( int j = expandedExtents.miny; j <= expandedExtents.maxy; j++ ) { gameDecalInfo_t* info = ( ( i >= extents.minx ) && ( i <= extents.maxx ) && ( j >= extents.miny ) && ( j <= extents.maxy ) ) ? decalInfo : decalInfoOuter; if ( !info ) { continue; } sdDeployMask::extents_t localExtents; localExtents.minx = i; localExtents.maxx = i; localExtents.miny = j; localExtents.maxy = j; mask->GetBounds( localExtents, bounds, heightMap ); top = bounds.GetCenter(); top[ 2 ] = bounds.GetMaxs()[ 2 ]; deployResult_t localResult = localPlayer->CheckBoundsForDeployment( localExtents, *mask, deployableObject, playZoneHeight ); bool hasTerritory; if ( localResult == DR_CLEAR ) { hasTerritory = gameLocal.TerritoryForPoint( top, localPlayer->GetGameTeam(), true ) != NULL; } else { hasTerritory = false; } if ( hasTerritory != lastTerritory[ terrIdx ] ) { regen = true; } lastTerritory[ terrIdx++ ] = hasTerritory; } } if ( expandedExtents.minx != lastExpandedExtents.minx || expandedExtents.maxx != lastExpandedExtents.maxx || expandedExtents.miny != lastExpandedExtents.miny || expandedExtents.maxy != lastExpandedExtents.maxy || regen ) { gameLocal.ResetLoggedDecal( decalHandle ); gameLocal.ResetLoggedDecal( decalHandleOuter ); lastExpandedExtents = expandedExtents; terrIdx = 0; for ( int i = expandedExtents.minx; i <= expandedExtents.maxx; i++ ) { for ( int j = expandedExtents.miny; j <= expandedExtents.maxy; j++ ) { gameDecalInfo_t* info = ( ( i >= extents.minx ) && ( i <= extents.maxx ) && ( j >= extents.miny ) && ( j <= extents.maxy ) ) ? decalInfo : decalInfoOuter; if ( !info ) { continue; } sdDeployMask::extents_t localExtents; localExtents.minx = i; localExtents.maxx = i; localExtents.miny = j; localExtents.maxy = j; mask->GetBounds( localExtents, bounds, heightMap ); top = bounds.GetCenter(); top[ 2 ] = bounds.GetMaxs()[ 2 ]; //bool hasTerritory = gameLocal.TerritoryForPoint( top, localPlayer->GetGameTeam(), true ) != NULL; deployResult_t localResult = localPlayer->CheckBoundsForDeployment( localExtents, *mask, deployableObject, playZoneHeight ); idVec4 localColor; switch ( localResult ) { case DR_CLEAR: if ( !lastTerritory[ terrIdx ] ) { localColor = colorOrange; } else { localColor = colorGreen; } break; case DR_WARNING: localColor = colorOrange; break; case DR_FAILED: localColor = colorDkRed; break; } winding.Clear(); winding += idVec5( idVec3( bounds.GetMins()[ 0 ], bounds.GetMins()[ 1 ], bounds.GetMins()[ 2 ] - depth ), idVec2( 0.0f, 0.0f ) ); winding += idVec5( idVec3( bounds.GetMins()[ 0 ], bounds.GetMaxs()[ 1 ], bounds.GetMins()[ 2 ] - depth ), idVec2( 0.0f, 1.0f ) ); winding += idVec5( idVec3( bounds.GetMaxs()[ 0 ], bounds.GetMaxs()[ 1 ], bounds.GetMins()[ 2 ] - depth ), idVec2( 1.0f, 1.0f ) ); winding += idVec5( idVec3( bounds.GetMaxs()[ 0 ], bounds.GetMins()[ 1 ], bounds.GetMins()[ 2 ] - depth ), idVec2( 1.0f, 0.0f ) ); // gameRenderWorld->DebugBounds( localColor, bounds ); // gameRenderWorld->DrawText( va( "%i %i", i, j ), top, 0.5, colorWhite, gameLocal.GetLocalPlayer()->GetRenderView()->viewaxis ); gameRenderWorld->AddToProjectedDecal( winding, top + idVec3( 0, 0, 64.f + depth ), true, localColor, info->renderEntity.hModel, spawnID, megaTextureMaterials.Begin(), megaTextureMaterials.Num() ); terrIdx++; } } } } else { gameLocal.ResetLoggedDecal( decalHandle ); gameLocal.ResetLoggedDecal( decalHandleOuter ); lastExpandedExtents.minx = -1; } idVec3 modelPos = position; if ( playZoneHeight ) { const sdHeightMapInstance& heightMap = playZoneHeight->GetHeightMap(); if ( heightMap.IsValid() ) { modelPos.z = heightMap.GetHeight( modelPos ); } } sdDeployRequest::UpdateRenderEntity( deployableRenderEntity, color, modelPos ); deployableRenderEntity.axis = rotationStart; gameRenderWorld->UpdateEntityDef( deployableRenderEntityHandle, &deployableRenderEntity ); } else { if ( deployableRenderEntityHandle >= 0 ) { gameRenderWorld->FreeEntityDef( deployableRenderEntityHandle ); deployableRenderEntityHandle = -1; } FreeDecals(); } }