/* ================ idBrittleFracture::CreateFractures ================ */ void idBrittleFracture::CreateFractures( const idRenderModel *renderModel ) { int i, j, k; const modelSurface_t *surf; const idDrawVert *v; idFixedWinding w; if ( !renderModel ) { return; } physicsObj.SetSelf( this ); physicsObj.SetOrigin( GetPhysics()->GetOrigin(), 0 ); physicsObj.SetAxis( GetPhysics()->GetAxis(), 0 ); for ( i = 0; i < 1 /*renderModel->NumSurfaces()*/; i++ ) { surf = renderModel->Surface( i ); material = surf->shader; for ( j = 0; j < surf->geometry->numIndexes; j += 3 ) { w.Clear(); for ( k = 0; k < 3; k++ ) { v = &surf->geometry->verts[ surf->geometry->indexes[ j + 2 - k ] ]; w.AddPoint( v->xyz ); w[k].s = v->st[0]; w[k].t = v->st[1]; } Fracture_r( w ); } } physicsObj.SetContents( material->GetContentFlags() ); SetPhysics( &physicsObj ); }
/* ================ idBrittleFracture::Fracture_r ================ */ void idBrittleFracture::Fracture_r( idFixedWinding &w ) { int i, j, bestPlane; float a, c, s, dist, bestDist; idVec3 origin; idPlane windingPlane, splitPlanes[2]; idMat3 axis, axistemp; idFixedWinding back; idTraceModel trm; idClipModel *clipModel; while( 1 ) { origin = w.GetCenter(); w.GetPlane( windingPlane ); if( w.GetArea() < maxShardArea ) { break; } // randomly create a split plane a = gameLocal.random.RandomFloat() * idMath::TWO_PI; c = cos( a ); s = -sin( a ); axis[2] = windingPlane.Normal(); axis[2].NormalVectors( axistemp[0], axistemp[1] ); axis[0] = axistemp[ 0 ] * c + axistemp[ 1 ] * s; axis[1] = axistemp[ 0 ] * s + axistemp[ 1 ] * -c; // get the best split plane bestDist = 0.0f; bestPlane = 0; for( i = 0; i < 2; i++ ) { splitPlanes[i].SetNormal( axis[i] ); splitPlanes[i].FitThroughPoint( origin ); for( j = 0; j < w.GetNumPoints(); j++ ) { dist = splitPlanes[i].Distance( w[j].ToVec3() ); if( dist > bestDist ) { bestDist = dist; bestPlane = i; } } } // split the winding if( !w.Split( &back, splitPlanes[bestPlane] ) ) { break; } // recursively create shards for the back winding Fracture_r( back ); } // translate the winding to it's center origin = w.GetCenter(); for( j = 0; j < w.GetNumPoints(); j++ ) { w[j].ToVec3() -= origin; } w.RemoveEqualPoints(); trm.SetupPolygon( w ); trm.Shrink( CM_CLIP_EPSILON ); clipModel = new idClipModel( trm ); physicsObj.SetClipModel( clipModel, 1.0f, shards.Num() ); physicsObj.SetOrigin( GetPhysics()->GetOrigin() + origin, shards.Num() ); physicsObj.SetAxis( GetPhysics()->GetAxis(), shards.Num() ); AddShard( clipModel, w ); }
/* ================ idBrittleFracture::CreateFractures ================ */ void idBrittleFracture::CreateFractures( const idRenderModel *renderModel ) { int i, j, k; const modelSurface_t *surf; const idDrawVert *v; idFixedWinding w; if ( !renderModel ) { return; } physicsObj.SetSelf( this ); physicsObj.SetOrigin( GetPhysics()->GetOrigin(), 0 ); physicsObj.SetAxis( GetPhysics()->GetAxis(), 0 ); for ( i = 0; i < 1 /*renderModel->NumSurfaces()*/; i++ ) { surf = renderModel->Surface( i ); material = surf->shader; for ( j = 0; j < surf->geometry->numIndexes; j += 3 ) { w.Clear(); for ( k = 0; k < 3; k++ ) { v = &surf->geometry->verts[ surf->geometry->indexes[ j + 2 - k ] ]; w.AddPoint( v->xyz ); w[k].s = v->st[0]; w[k].t = v->st[1]; } Fracture_r( w ); } } physicsObj.SetContents( material->GetContentFlags() ); // ishtvan: overwrite with custom contents if present if( m_CustomContents != -1 ) physicsObj.SetContents( m_CustomContents ); // SR CONTENTS_RESONSE FIX if( m_StimResponseColl->HasResponse() ) physicsObj.SetContents( physicsObj.GetContents() | CONTENTS_RESPONSE ); SetPhysics( &physicsObj ); }
/* ================ 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 ); }