/* ============ idTraceModel::SetupOctahedron ============ */ void idTraceModel::SetupOctahedron( const idBounds &octBounds ) { int i, e0, e1, v0, v1, v2; idVec3 v; if ( type != TRM_OCTAHEDRON ) { InitOctahedron(); } offset = ( octBounds[0] + octBounds[1] ) * 0.5f; v[0] = octBounds[1][0] - offset[0]; v[1] = octBounds[1][1] - offset[1]; v[2] = octBounds[1][2] - offset[2]; // set vertices verts[0].Set( offset.x + v[0], offset.y, offset.z ); verts[1].Set( offset.x - v[0], offset.y, offset.z ); verts[2].Set( offset.x, offset.y + v[1], offset.z ); verts[3].Set( offset.x, offset.y - v[1], offset.z ); verts[4].Set( offset.x, offset.y, offset.z + v[2] ); verts[5].Set( offset.x, offset.y, offset.z - v[2] ); // set polygons for ( i = 0; i < numPolys; i++ ) { e0 = polys[i].edges[0]; e1 = polys[i].edges[1]; v0 = edges[abs(e0)].v[INTSIGNBITSET(e0)]; v1 = edges[abs(e0)].v[INTSIGNBITNOTSET(e0)]; v2 = edges[abs(e1)].v[INTSIGNBITNOTSET(e1)]; // polygon plane polys[i].normal = ( verts[v1] - verts[v0] ).Cross( verts[v2] - verts[v0] ); polys[i].normal.Normalize(); polys[i].dist = polys[i].normal * verts[v0]; // polygon bounds polys[i].bounds[0] = polys[i].bounds[1] = verts[v0]; polys[i].bounds.AddPoint( verts[v1] ); polys[i].bounds.AddPoint( verts[v2] ); } // trm bounds bounds = octBounds; GenerateEdgeNormals(); }
/* ============ idTraceModel::SetupBone The origin is placed at the center of the bone. ============ */ void idTraceModel::SetupBone( const float length, const float width ) { int i, j, edgeNum; float halfLength = length * 0.5f; if ( type != TRM_BONE ) { InitBone(); } // offset to center offset.Set( 0.0f, 0.0f, 0.0f ); // set vertices verts[0].Set( 0.0f, 0.0f, -halfLength ); verts[1].Set( 0.0f, width * -0.5f, 0.0f ); verts[2].Set( width * 0.5f, width * 0.25f, 0.0f ); verts[3].Set( width * -0.5f, width * 0.25f, 0.0f ); verts[4].Set( 0.0f, 0.0f, halfLength ); // set bounds bounds[0].Set( width * -0.5f, width * -0.5f, -halfLength ); bounds[1].Set( width * 0.5f, width * 0.25f, halfLength ); // poly plane normals polys[0].normal = ( verts[2] - verts[0] ).Cross( verts[1] - verts[0] ); polys[0].normal.Normalize(); polys[2].normal.Set( -polys[0].normal[0], polys[0].normal[1], polys[0].normal[2] ); polys[3].normal.Set( polys[0].normal[0], polys[0].normal[1], -polys[0].normal[2] ); polys[5].normal.Set( -polys[0].normal[0], polys[0].normal[1], -polys[0].normal[2] ); polys[1].normal = (verts[3] - verts[0]).Cross(verts[2] - verts[0]); polys[1].normal.Normalize(); polys[4].normal.Set( polys[1].normal[0], polys[1].normal[1], -polys[1].normal[2] ); // poly plane distances for ( i = 0; i < 6; i++ ) { polys[i].dist = polys[i].normal * verts[ edges[ abs(polys[i].edges[0]) ].v[0] ]; polys[i].bounds.Clear(); for ( j = 0; j < 3; j++ ) { edgeNum = polys[i].edges[ j ]; polys[i].bounds.AddPoint( verts[ edges[abs(edgeNum)].v[edgeNum < 0] ] ); } } dlog(DEBUG_CM, "idTraceModel::SetupBone bounds %s %s\n", bounds[0].ToString(), bounds[1].ToString()); GenerateEdgeNormals(); }
/* ============ idTraceModel::Rotate ============ */ void idTraceModel::Rotate( const idMat3 &rotation ) { int i, j, edgeNum; for ( i = 0; i < numVerts; i++ ) { verts[i] *= rotation; } bounds.Clear(); for ( i = 0; i < numPolys; i++ ) { polys[i].normal *= rotation; polys[i].bounds.Clear(); edgeNum = 0; for ( j = 0; j < polys[i].numEdges; j++ ) { edgeNum = polys[i].edges[j]; polys[i].bounds.AddPoint( verts[edges[abs(edgeNum)].v[INTSIGNBITSET(edgeNum)]] ); } polys[i].dist = polys[i].normal * verts[edges[abs(edgeNum)].v[INTSIGNBITSET(edgeNum)]]; bounds += polys[i].bounds; } GenerateEdgeNormals(); }
/* ============ idTraceModel::InitBox Initialize size independent box. ============ */ void idTraceModel::InitBox( void ) { int i; type = TRM_BOX; numVerts = 8; numEdges = 12; numPolys = 6; // set box edges for ( i = 0; i < 4; i++ ) { edges[ i + 1 ].v[0] = i; edges[ i + 1 ].v[1] = (i + 1) & 3; edges[ i + 5 ].v[0] = 4 + i; edges[ i + 5 ].v[1] = 4 + ((i + 1) & 3); edges[ i + 9 ].v[0] = i; edges[ i + 9 ].v[1] = 4 + i; } // all edges of a polygon go counter clockwise polys[0].numEdges = 4; polys[0].edges[0] = -4; polys[0].edges[1] = -3; polys[0].edges[2] = -2; polys[0].edges[3] = -1; polys[0].normal.Set( 0.0f, 0.0f, -1.0f ); polys[1].numEdges = 4; polys[1].edges[0] = 5; polys[1].edges[1] = 6; polys[1].edges[2] = 7; polys[1].edges[3] = 8; polys[1].normal.Set( 0.0f, 0.0f, 1.0f ); polys[2].numEdges = 4; polys[2].edges[0] = 1; polys[2].edges[1] = 10; polys[2].edges[2] = -5; polys[2].edges[3] = -9; polys[2].normal.Set( 0.0f, -1.0f, 0.0f ); polys[3].numEdges = 4; polys[3].edges[0] = 2; polys[3].edges[1] = 11; polys[3].edges[2] = -6; polys[3].edges[3] = -10; polys[3].normal.Set( 1.0f, 0.0f, 0.0f ); polys[4].numEdges = 4; polys[4].edges[0] = 3; polys[4].edges[1] = 12; polys[4].edges[2] = -7; polys[4].edges[3] = -11; polys[4].normal.Set( 0.0f, 1.0f, 0.0f ); polys[5].numEdges = 4; polys[5].edges[0] = 4; polys[5].edges[1] = 9; polys[5].edges[2] = -8; polys[5].edges[3] = -12; polys[5].normal.Set( -1.0f, 0.0f, 0.0f ); // convex model isConvex = true; GenerateEdgeNormals(); }
/* ============ idTraceModel::SetupCone ============ */ void idTraceModel::SetupCone( const idBounds &coneBounds, const int numSides ) { int i, n, ii; float angle; idVec3 halfSize; n = numSides; if ( n < 2 ) { n = 3; } if ( n + 1 > MAX_TRACEMODEL_VERTS ) { idLib::common->Printf( "WARNING: idTraceModel::SetupCone: too many vertices\n" ); n = MAX_TRACEMODEL_VERTS - 1; } if ( n * 2 > MAX_TRACEMODEL_EDGES ) { idLib::common->Printf( "WARNING: idTraceModel::SetupCone: too many edges\n" ); n = MAX_TRACEMODEL_EDGES / 2; } if ( n + 1 > MAX_TRACEMODEL_POLYS ) { idLib::common->Printf( "WARNING: idTraceModel::SetupCone: too many polygons\n" ); n = MAX_TRACEMODEL_POLYS - 1; } type = TRM_CONE; numVerts = n + 1; numEdges = n * 2; numPolys = n + 1; offset = ( coneBounds[0] + coneBounds[1] ) * 0.5f; halfSize = coneBounds[1] - offset; verts[n].Set( 0.0f, 0.0f, halfSize.z + offset.z ); for ( i = 0; i < n; i++ ) { // verts angle = idMath::TWO_PI * i / n; // RAVEN BEGIN verts[i].x = idMath::Cos( angle ) * halfSize.x + offset.x; verts[i].y = idMath::Sin( angle ) * halfSize.y + offset.y; // RAVEN END verts[i].z = -halfSize.z + offset.z; // edges ii = i + 1; edges[ii].v[0] = i; edges[ii].v[1] = ii % n; edges[n+ii].v[0] = i; edges[n+ii].v[1] = n; // vertical polygon edges polys[i].numEdges = 3; polys[i].edges[0] = ii; polys[i].edges[1] = n + (ii % n) + 1; polys[i].edges[2] = -(n + ii); // bottom polygon edges polys[n].edges[i] = -(n - i); } // bottom polygon numEdges polys[n].numEdges = n; // polygons for ( i = 0; i < n; i++ ) { // polygon plane polys[i].normal = (verts[(i+1)%n] - verts[i]).Cross( verts[n] - verts[i] ); polys[i].normal.Normalize(); polys[i].dist = polys[i].normal * verts[i]; // polygon bounds polys[i].bounds.Clear(); polys[i].bounds.AddPoint( verts[i] ); polys[i].bounds.AddPoint( verts[(i+1)%n] ); polys[i].bounds.AddPoint( verts[n] ); } // bottom polygon plane polys[n].normal.Set( 0.0f, 0.0f, -1.0f ); polys[n].dist = -coneBounds[0][2]; // trm bounds bounds = coneBounds; // bottom polygon bounds polys[n].bounds = bounds; polys[n].bounds[1][2] = bounds[0][2]; // convex model isConvex = true; GenerateEdgeNormals(); }
/* ============ idTraceModel::SetupDodecahedron ============ */ void idTraceModel::SetupDodecahedron( const idBounds &dodBounds ) { int i, e0, e1, e2, e3, v0, v1, v2, v3, v4; float s, d; idVec3 a, b, c; if ( type != TRM_DODECAHEDRON ) { InitDodecahedron(); } a[0] = a[1] = a[2] = 0.5773502691896257f; // 1.0f / ( 3.0f ) ^ 0.5f; b[0] = b[1] = b[2] = 0.3568220897730899f; // ( ( 3.0f - ( 5.0f ) ^ 0.5f ) / 6.0f ) ^ 0.5f; c[0] = c[1] = c[2] = 0.9341723589627156f; // ( ( 3.0f + ( 5.0f ) ^ 0.5f ) / 6.0f ) ^ 0.5f; d = 0.5f / c[0]; s = ( dodBounds[1][0] - dodBounds[0][0] ) * d; a[0] *= s; b[0] *= s; c[0] *= s; s = ( dodBounds[1][1] - dodBounds[0][1] ) * d; a[1] *= s; b[1] *= s; c[1] *= s; s = ( dodBounds[1][2] - dodBounds[0][2] ) * d; a[2] *= s; b[2] *= s; c[2] *= s; offset = ( dodBounds[0] + dodBounds[1] ) * 0.5f; // set vertices verts[ 0].Set( offset.x + a[0], offset.y + a[1], offset.z + a[2] ); verts[ 1].Set( offset.x + a[0], offset.y + a[1], offset.z - a[2] ); verts[ 2].Set( offset.x + a[0], offset.y - a[1], offset.z + a[2] ); verts[ 3].Set( offset.x + a[0], offset.y - a[1], offset.z - a[2] ); verts[ 4].Set( offset.x - a[0], offset.y + a[1], offset.z + a[2] ); verts[ 5].Set( offset.x - a[0], offset.y + a[1], offset.z - a[2] ); verts[ 6].Set( offset.x - a[0], offset.y - a[1], offset.z + a[2] ); verts[ 7].Set( offset.x - a[0], offset.y - a[1], offset.z - a[2] ); verts[ 8].Set( offset.x + b[0], offset.y + c[1], offset.z ); verts[ 9].Set( offset.x - b[0], offset.y + c[1], offset.z ); verts[10].Set( offset.x + b[0], offset.y - c[1], offset.z ); verts[11].Set( offset.x - b[0], offset.y - c[1], offset.z ); verts[12].Set( offset.x + c[0], offset.y , offset.z + b[2] ); verts[13].Set( offset.x + c[0], offset.y , offset.z - b[2] ); verts[14].Set( offset.x - c[0], offset.y , offset.z + b[2] ); verts[15].Set( offset.x - c[0], offset.y , offset.z - b[2] ); verts[16].Set( offset.x , offset.y + b[1], offset.z + c[2] ); verts[17].Set( offset.x , offset.y - b[1], offset.z + c[2] ); verts[18].Set( offset.x , offset.y + b[1], offset.z - c[2] ); verts[19].Set( offset.x , offset.y - b[1], offset.z - c[2] ); // set polygons for ( i = 0; i < numPolys; i++ ) { e0 = polys[i].edges[0]; e1 = polys[i].edges[1]; e2 = polys[i].edges[2]; e3 = polys[i].edges[3]; v0 = edges[abs(e0)].v[INTSIGNBITSET(e0)]; v1 = edges[abs(e0)].v[INTSIGNBITNOTSET(e0)]; v2 = edges[abs(e1)].v[INTSIGNBITNOTSET(e1)]; v3 = edges[abs(e2)].v[INTSIGNBITNOTSET(e2)]; v4 = edges[abs(e3)].v[INTSIGNBITNOTSET(e3)]; // polygon plane polys[i].normal = ( verts[v1] - verts[v0] ).Cross( verts[v2] - verts[v0] ); polys[i].normal.Normalize(); polys[i].dist = polys[i].normal * verts[v0]; // polygon bounds polys[i].bounds[0] = polys[i].bounds[1] = verts[v0]; polys[i].bounds.AddPoint( verts[v1] ); polys[i].bounds.AddPoint( verts[v2] ); polys[i].bounds.AddPoint( verts[v3] ); polys[i].bounds.AddPoint( verts[v4] ); } // trm bounds bounds = dodBounds; GenerateEdgeNormals(); }
/* ============ idTraceModel::SetupCylinder alt_alignment makes even-sided cylinders align faces with the x/y axes ============ */ void idTraceModel::SetupCylinder( const idBounds &cylBounds, const int numSides, const bool alt_alignment ) { int i, n, ii, n2; float angle; idVec3 halfSize; n = numSides; if ( n < 3 ) { n = 3; } if ( n * 2 > MAX_TRACEMODEL_VERTS ) { idLib::common->Printf( "WARNING: idTraceModel::SetupCylinder: too many vertices\n" ); n = MAX_TRACEMODEL_VERTS / 2; } if ( n * 3 > MAX_TRACEMODEL_EDGES ) { idLib::common->Printf( "WARNING: idTraceModel::SetupCylinder: too many sides\n" ); n = MAX_TRACEMODEL_EDGES / 3; } if ( n + 2 > MAX_TRACEMODEL_POLYS ) { idLib::common->Printf( "WARNING: idTraceModel::SetupCylinder: too many polygons\n" ); n = MAX_TRACEMODEL_POLYS - 2; } float angle_bias = alt_alignment ? (idMath::PI / n) : 0.0f; type = TRM_CYLINDER; numVerts = n * 2; numEdges = n * 3; numPolys = n + 2; offset = ( cylBounds[0] + cylBounds[1] ) * 0.5f; halfSize = cylBounds[1] - offset; for ( i = 0; i < n; i++ ) { // verts angle = (idMath::TWO_PI * i / n) + angle_bias; verts[i].x = idMath::Cos( angle ) * halfSize.x + offset.x; verts[i].y = idMath::Sin( angle ) * halfSize.y + offset.y; verts[i].z = -halfSize.z + offset.z; verts[n+i].x = verts[i].x; verts[n+i].y = verts[i].y; verts[n+i].z = halfSize.z + offset.z; // edges ii = i + 1; n2 = n << 1; edges[ii].v[0] = i; edges[ii].v[1] = ii % n; edges[n+ii].v[0] = edges[ii].v[0] + n; edges[n+ii].v[1] = edges[ii].v[1] + n; edges[n2+ii].v[0] = i; edges[n2+ii].v[1] = n + i; // vertical polygon edges polys[i].numEdges = 4; polys[i].edges[0] = ii; polys[i].edges[1] = n2 + (ii % n) + 1; polys[i].edges[2] = -(n + ii); polys[i].edges[3] = -(n2 + ii); // bottom and top polygon edges polys[n].edges[i] = -(n - i); polys[n+1].edges[i] = n + ii; } // bottom and top polygon numEdges polys[n].numEdges = n; polys[n+1].numEdges = n; // polygons for ( i = 0; i < n; i++ ) { // vertical polygon plane polys[i].normal = (verts[(i+1)%n] - verts[i]).Cross( verts[n+i] - verts[i] ); polys[i].normal.Normalize(); polys[i].dist = polys[i].normal * verts[i]; // vertical polygon bounds polys[i].bounds.Clear(); polys[i].bounds.AddPoint( verts[i] ); polys[i].bounds.AddPoint( verts[(i+1)%n] ); polys[i].bounds[0][2] = -halfSize.z + offset.z; polys[i].bounds[1][2] = halfSize.z + offset.z; } // bottom and top polygon plane polys[n].normal.Set( 0.0f, 0.0f, -1.0f ); polys[n].dist = -cylBounds[0][2]; polys[n+1].normal.Set( 0.0f, 0.0f, 1.0f ); polys[n+1].dist = cylBounds[1][2]; // trm bounds bounds = cylBounds; // bottom and top polygon bounds polys[n].bounds = bounds; polys[n].bounds[1][2] = bounds[0][2]; polys[n+1].bounds = bounds; polys[n+1].bounds[0][2] = bounds[1][2]; // convex model isConvex = true; GenerateEdgeNormals(); }