/* ==================== idSurface_Polytope::SetupTetrahedron ==================== */ void idSurface_Polytope::SetupTetrahedron( const idBounds &bounds ) { idVec3 center, scale; float c1, c2, c3; c1 = 0.4714045207f; c2 = 0.8164965809f; c3 = -0.3333333333f; center = bounds.GetCenter(); scale = bounds[1] - center; verts.SetNum( 4 ); verts[0].xyz = center + idVec3( 0.0f, 0.0f, scale.z ); verts[1].xyz = center + idVec3( 2.0f * c1 * scale.x, 0.0f, c3 * scale.z ); verts[2].xyz = center + idVec3( -c1 * scale.x, c2 * scale.y, c3 * scale.z ); verts[3].xyz = center + idVec3( -c1 * scale.x, -c2 * scale.y, c3 * scale.z ); indexes.SetNum( 4*3 ); indexes[0*3+0] = 0; indexes[0*3+1] = 1; indexes[0*3+2] = 2; indexes[1*3+0] = 0; indexes[1*3+1] = 2; indexes[1*3+2] = 3; indexes[2*3+0] = 0; indexes[2*3+1] = 3; indexes[2*3+2] = 1; indexes[3*3+0] = 1; indexes[3*3+1] = 3; indexes[3*3+2] = 2; GenerateEdgeIndexes(); }
/* ================= idSurface_Patch::GenerateIndexes ================= */ void idSurface_Patch::GenerateIndexes() { int i, j, v1, v2, v3, v4, index; indexes.SetNum( ( width - 1 ) * ( height - 1 ) * 2 * 3 ); index = 0; for( i = 0; i < width - 1; i++ ) { for( j = 0; j < height - 1; j++ ) { v1 = j * width + i; v2 = v1 + 1; v3 = v1 + width + 1; v4 = v1 + width; indexes[index++] = v1; indexes[index++] = v3; indexes[index++] = v2; indexes[index++] = v1; indexes[index++] = v4; indexes[index++] = v3; } } GenerateEdgeIndexes(); }
/* ==================== idSurface_Polytope::SetupHexahedron ==================== */ void idSurface_Polytope::SetupHexahedron(const idBounds &bounds) { idVec3 center, scale; center = bounds.GetCenter(); scale = bounds[1] - center; verts.SetNum(8); verts[0].xyz = center + idVec3(-scale.x, -scale.y, -scale.z); verts[1].xyz = center + idVec3(scale.x, -scale.y, -scale.z); verts[2].xyz = center + idVec3(scale.x, scale.y, -scale.z); verts[3].xyz = center + idVec3(-scale.x, scale.y, -scale.z); verts[4].xyz = center + idVec3(-scale.x, -scale.y, scale.z); verts[5].xyz = center + idVec3(scale.x, -scale.y, scale.z); verts[6].xyz = center + idVec3(scale.x, scale.y, scale.z); verts[7].xyz = center + idVec3(-scale.x, scale.y, scale.z); indexes.SetNum(12*3); indexes[ 0*3+0] = 0; indexes[ 0*3+1] = 3; indexes[ 0*3+2] = 2; indexes[ 1*3+0] = 0; indexes[ 1*3+1] = 2; indexes[ 1*3+2] = 1; indexes[ 2*3+0] = 0; indexes[ 2*3+1] = 1; indexes[ 2*3+2] = 5; indexes[ 3*3+0] = 0; indexes[ 3*3+1] = 5; indexes[ 3*3+2] = 4; indexes[ 4*3+0] = 0; indexes[ 4*3+1] = 4; indexes[ 4*3+2] = 7; indexes[ 5*3+0] = 0; indexes[ 5*3+1] = 7; indexes[ 5*3+2] = 3; indexes[ 6*3+0] = 6; indexes[ 6*3+1] = 5; indexes[ 6*3+2] = 1; indexes[ 7*3+0] = 6; indexes[ 7*3+1] = 1; indexes[ 7*3+2] = 2; indexes[ 8*3+0] = 6; indexes[ 8*3+1] = 2; indexes[ 8*3+2] = 3; indexes[ 9*3+0] = 6; indexes[ 9*3+1] = 3; indexes[ 9*3+2] = 7; indexes[10*3+0] = 6; indexes[10*3+1] = 7; indexes[10*3+2] = 4; indexes[11*3+0] = 6; indexes[11*3+1] = 4; indexes[11*3+2] = 5; GenerateEdgeIndexes(); }
/* ==================== idSurface_Polytope::FromPlanes ==================== */ void idSurface_Polytope::FromPlanes( const idPlane* planes, const int numPlanes ) { int i, j, k, *windingVerts; idFixedWinding w; idDrawVert newVert; windingVerts = ( int* ) _alloca( MAX_POINTS_ON_WINDING * sizeof( int ) ); memset( &newVert, 0, sizeof( newVert ) ); for( i = 0; i < numPlanes; i++ ) { w.BaseForPlane( planes[i] ); for( j = 0; j < numPlanes; j++ ) { if( j == i ) { continue; } if( !w.ClipInPlace( -planes[j], ON_EPSILON, true ) ) { break; } } if( !w.GetNumPoints() ) { continue; } for( j = 0; j < w.GetNumPoints(); j++ ) { for( k = 0; k < verts.Num(); k++ ) { if( verts[k].xyz.Compare( w[j].ToVec3(), POLYTOPE_VERTEX_EPSILON ) ) { break; } } if( k >= verts.Num() ) { newVert.xyz = w[j].ToVec3(); k = verts.Append( newVert ); } windingVerts[j] = k; } for( j = 2; j < w.GetNumPoints(); j++ ) { indexes.Append( windingVerts[0] ); indexes.Append( windingVerts[j - 1] ); indexes.Append( windingVerts[j] ); } } GenerateEdgeIndexes(); }
/* ==================== idSurface_Polytope::SetupOctahedron ==================== */ void idSurface_Polytope::SetupOctahedron(const idBounds &bounds) { idVec3 center, scale; center = bounds.GetCenter(); scale = bounds[1] - center; verts.SetNum(6); verts[0].xyz = center + idVec3(scale.x, 0.0f, 0.0f); verts[1].xyz = center + idVec3(-scale.x, 0.0f, 0.0f); verts[2].xyz = center + idVec3(0.0f, scale.y, 0.0f); verts[3].xyz = center + idVec3(0.0f, -scale.y, 0.0f); verts[4].xyz = center + idVec3(0.0f, 0.0f, scale.z); verts[5].xyz = center + idVec3(0.0f, 0.0f, -scale.z); indexes.SetNum(8*3); indexes[0*3+0] = 4; indexes[0*3+1] = 0; indexes[0*3+2] = 2; indexes[1*3+0] = 4; indexes[1*3+1] = 2; indexes[1*3+2] = 1; indexes[2*3+0] = 4; indexes[2*3+1] = 1; indexes[2*3+2] = 3; indexes[3*3+0] = 4; indexes[3*3+1] = 3; indexes[3*3+2] = 0; indexes[4*3+0] = 5; indexes[4*3+1] = 2; indexes[4*3+2] = 0; indexes[5*3+0] = 5; indexes[5*3+1] = 1; indexes[5*3+2] = 2; indexes[6*3+0] = 5; indexes[6*3+1] = 3; indexes[6*3+2] = 1; indexes[7*3+0] = 5; indexes[7*3+1] = 0; indexes[7*3+2] = 3; GenerateEdgeIndexes(); }
/* ==================== idSurface_SweptSpline::Tessellate tesselate the surface ==================== */ void idSurface_SweptSpline::Tessellate( const int splineSubdivisions, const int sweptSplineSubdivisions ) { int i, j, offset, baseOffset, splineDiv, sweptSplineDiv; int i0, i1, j0, j1; float totalTime, t; idVec4 splinePos, splineD1; idMat3 splineMat; if ( !spline || !sweptSpline ) { idSurface::Clear(); return; } verts.SetNum( splineSubdivisions * sweptSplineSubdivisions, false ); // calculate the points and first derivatives for the swept spline totalTime = sweptSpline->GetTime( sweptSpline->GetNumValues() - 1 ) - sweptSpline->GetTime( 0 ) + sweptSpline->GetCloseTime(); sweptSplineDiv = sweptSpline->GetBoundaryType() == idCurve_Spline<idVec3>::BT_CLOSED ? sweptSplineSubdivisions : sweptSplineSubdivisions - 1; baseOffset = (splineSubdivisions-1) * sweptSplineSubdivisions; for ( i = 0; i < sweptSplineSubdivisions; i++ ) { t = totalTime * i / sweptSplineDiv; splinePos = sweptSpline->GetCurrentValue( t ); splineD1 = sweptSpline->GetCurrentFirstDerivative( t ); verts[baseOffset+i].xyz = splinePos.ToVec3(); verts[baseOffset+i].st[0] = splinePos.w; verts[baseOffset+i].tangents[0] = splineD1.ToVec3(); } // sweep the spline totalTime = spline->GetTime( spline->GetNumValues() - 1 ) - spline->GetTime( 0 ) + spline->GetCloseTime(); splineDiv = spline->GetBoundaryType() == idCurve_Spline<idVec3>::BT_CLOSED ? splineSubdivisions : splineSubdivisions - 1; splineMat.Identity(); for ( i = 0; i < splineSubdivisions; i++ ) { t = totalTime * i / splineDiv; splinePos = spline->GetCurrentValue( t ); splineD1 = spline->GetCurrentFirstDerivative( t ); GetFrame( splineMat, splineD1.ToVec3(), splineMat ); offset = i * sweptSplineSubdivisions; for ( j = 0; j < sweptSplineSubdivisions; j++ ) { idDrawVert *v = &verts[offset+j]; v->xyz = splinePos.ToVec3() + verts[baseOffset+j].xyz * splineMat; v->st[0] = verts[baseOffset+j].st[0]; v->st[1] = splinePos.w; v->tangents[0] = verts[baseOffset+j].tangents[0] * splineMat; v->tangents[1] = splineD1.ToVec3(); v->normal = v->tangents[1].Cross( v->tangents[0] ); v->normal.Normalize(); v->color[0] = v->color[1] = v->color[2] = v->color[3] = 0; } } indexes.SetNum( splineDiv * sweptSplineDiv * 2 * 3, false ); // create indexes for the triangles for ( offset = i = 0; i < splineDiv; i++ ) { i0 = (i+0) * sweptSplineSubdivisions; i1 = (i+1) % splineSubdivisions * sweptSplineSubdivisions; for ( j = 0; j < sweptSplineDiv; j++ ) { j0 = (j+0); j1 = (j+1) % sweptSplineSubdivisions; indexes[offset++] = i0 + j0; indexes[offset++] = i0 + j1; indexes[offset++] = i1 + j1; indexes[offset++] = i1 + j1; indexes[offset++] = i1 + j0; indexes[offset++] = i0 + j0; } } GenerateEdgeIndexes(); }