void Face3::Flip() { Edge3 tmp = edge[1]; edge[1] = edge[2]; edge[2] = tmp; MakeNormal(); }
Face3::Face3(int i0, int i1, int i2) { edge[0] = Edge3(i0, i1); edge[1] = Edge3(i1, i2); edge[2] = Edge3(i2, i0); neigh = NO_LINK; MakeNormal(); flag = GEOM_UNKNOWN_STATE; }
Face3::Face3(Edge3& e0, Edge3& e1, Edge3& e2) { edge[0] = e0; edge[1] = e1; edge[2] = e2; neigh = NO_LINK; MakeNormal(); flag = GEOM_UNKNOWN_STATE; }
Face3::Face3( const Face3& face) { edge[0] = face.edge[0]; edge[1] = face.edge[1]; edge[2] = face.edge[2]; neigh = NO_LINK; MakeNormal(); flag = GEOM_UNKNOWN_STATE; }
bool IntersectPolygon (TPolygon p, TVector3 *v) { TRay ray; TVector3 nml, edge_nml, edge_vec; TVector3 pt; double d, s, nuDotProd, wec; double edge_len, t, distsq; int i; nml = MakeNormal (p, v); ray.pt = MakeVector (0., 0., 0.); ray.vec = nml; nuDotProd = DotProduct (nml, ray.vec); if (fabs(nuDotProd) < EPS) return false; d = - (nml.x * v[p.vertices[0]].x + nml.y * v[p.vertices[0]].y + nml.z * v[p.vertices[0]].z); if (fabs (d) > 1) return false; for (i=0; i < p.num_vertices; i++) { TVector3 *v0, *v1; v0 = &v[p.vertices[i]]; v1 = &v[p.vertices[ (i+1) % p.num_vertices ]]; edge_vec = SubtractVectors (*v1, *v0); edge_len = NormVector (&edge_vec); t = - DotProduct (*((TVector3 *) v0), edge_vec); if (t < 0) { distsq = MAG_SQD2 (*v0); } else if (t > edge_len) { distsq = MAG_SQD2 (*v1); } else { *v0 = AddVectors (*v0, ScaleVector (t, edge_vec)); distsq = MAG_SQD2 (*v0); } if (distsq <= 1) return true; } s = - (d + DotProduct (nml, MakeVector (ray.pt.x, ray.pt.y, ray.pt.z))) / nuDotProd; pt = AddVectors (ray.pt, ScaleVector (s, ray.vec)); for (i=0; i < p.num_vertices; i++) { edge_nml = CrossProduct (nml, SubtractVectors (v[p.vertices[ (i+1) % p.num_vertices ]], v[p.vertices[i]])); wec = DotProduct (SubtractVectors (pt, v[p.vertices[i]]), edge_nml); if (wec < 0) return false; } return true; }
Face3::Face3(int i0, int i1, int i2, Vertex3 *commonPool) { edge[0] = Edge3(i0, i1); edge[1] = Edge3(i1, i2); edge[2] = Edge3(i2, i0); edge[0].SetLocalVertexList(commonPool); edge[1].SetLocalVertexList(commonPool); edge[2].SetLocalVertexList(commonPool); neigh = NO_LINK; MakeNormal(); flag = GEOM_UNKNOWN_STATE; }
void DoFlipTerrain( void ) { vec3_t vUp = { 0.f, 0.f, 1.f }; int i; // ensure we have something selected if ( g_FuncTable.m_pfnSelectedBrushCount() != 2 ) { DoMessageBox( "Invalid number of objects selected, chose 2 only", "Error", MB_OK ); return; } g_FuncTable.m_pfnAllocateSelectedBrushHandles(); brush_t* brushes[2]; for ( i = 0; i < 2; i++ ) { brushes[i] = (brush_t*)g_FuncTable.m_pfnGetSelectedBrushHandle( i ); } DBrush Brushes[2]; DPlane* Planes[2]; pntTripple Points[2]; for ( i = 0; i < 2; i++ ) { Brushes[i].LoadFromBrush_t( brushes[i], false ); if ( !( Planes[i] = Brushes[i].FindPlaneWithClosestNormal( vUp ) ) || Brushes[i].FindPointsForPlane( Planes[i], Points[i], 3 ) != 3 ) { g_FuncTable.m_pfnReleaseSelectedBrushHandles(); DoMessageBox( "Error", "Error", MB_OK ); return; } } vec3_t mins1, mins2, maxs1, maxs2; Brushes[0].GetBounds( mins1, maxs1 ); Brushes[1].GetBounds( mins2, maxs2 ); entity_t* ents[2]; for ( i = 0; i < 2; i++ ) { ents[i] = brushes[i]->owner; Brushes[i].RemoveFromRadiant(); } g_FuncTable.m_pfnReleaseSelectedBrushHandles(); int dontmatch[2] = { -1, -1 }; bool found = false; for ( i = 0; i < 3; i++ ) { for ( int j = 0; j < 3 && !found; j++ ) { if ( VectorCompare( ( Points[0] )[i]->_pnt, ( Points[1] )[j]->_pnt ) ) { found = true; break; } } if ( !found ) { dontmatch[0] = i; break; } found = false; } if ( dontmatch[0] == -1 ) { DoMessageBox( "Error", "Error", MB_OK ); return; } for ( i = 0; i < 3; i++ ) { for ( int j = 0; j < 3 && !found; j++ ) { if ( VectorCompare( ( Points[1] )[i]->_pnt, ( Points[0] )[j]->_pnt ) ) { found = true; break; } } if ( !found ) { dontmatch[1] = i; break; } found = false; } if ( dontmatch[1] == -1 ) { DoMessageBox( "Error", "Error", MB_OK ); return; } vec3_t plnpnts1[3]; vec3_t plnpnts2[3]; vec3_t plnpntsshr[3]; VectorCopy( ( Points[0] )[dontmatch[0]]->_pnt, plnpnts1[0] ); for ( i = 0; i < 3; i++ ) { if ( dontmatch[0] != i ) { VectorCopy( ( Points[0] )[i]->_pnt, plnpnts1[1] ); break; } } VectorCopy( ( Points[1] )[dontmatch[1]]->_pnt, plnpnts1[2] ); VectorCopy( ( Points[1] )[dontmatch[1]]->_pnt, plnpnts2[0] ); for ( i = 0; i < 3; i++ ) { if ( dontmatch[1] != i && !VectorCompare( ( Points[1] )[i]->_pnt, plnpnts1[1] ) ) { VectorCopy( ( Points[1] )[i]->_pnt, plnpnts2[1] ); break; } } VectorCopy( ( Points[0] )[dontmatch[0]]->_pnt, plnpnts2[2] ); VectorCopy( ( Points[0] )[dontmatch[0]]->_pnt, plnpntsshr[0] ); VectorCopy( ( Points[1] )[dontmatch[1]]->_pnt, plnpntsshr[1] ); if ( ( Points[1] )[dontmatch[1]]->_pnt[2] < ( Points[0] )[dontmatch[0]]->_pnt[2] ) { VectorCopy( ( Points[1] )[dontmatch[1]]->_pnt, plnpntsshr[2] ); } else { VectorCopy( ( Points[0] )[dontmatch[0]]->_pnt, plnpntsshr[2] ); } plnpntsshr[2][2] -= 16; for ( i = 0; i < 3; i++ ) { if ( mins2[i] < mins1[i] ) { mins1[i] = mins2[i]; } if ( maxs2[i] > maxs1[i] ) { maxs1[i] = maxs2[i]; } } DBrush* newBrushes[2]; newBrushes[0] = DShape::GetBoundingCube_Ext( mins1, maxs1, "textures/common/caulk", bFacesAll, true ); newBrushes[1] = DShape::GetBoundingCube_Ext( mins1, maxs1, "textures/common/caulk", bFacesAll, true ); vec3_t normal; MakeNormal( plnpnts1[0], plnpnts1[1], plnpnts1[2], normal ); if ( normal[2] >= 0 ) { newBrushes[0]->AddFace( plnpnts1[0], plnpnts1[1], plnpnts1[2], "textures/common/terrain", true ); } else { newBrushes[0]->AddFace( plnpnts1[2], plnpnts1[1], plnpnts1[0], "textures/common/terrain", true ); } MakeNormal( plnpnts2[0], plnpnts2[1], plnpnts2[2], normal ); if ( normal[2] >= 0 ) { newBrushes[1]->AddFace( plnpnts2[0], plnpnts2[1], plnpnts2[2], "textures/common/terrain", true ); } else { newBrushes[1]->AddFace( plnpnts2[2], plnpnts2[1], plnpnts2[0], "textures/common/terrain", true ); } vec3_t vec; MakeNormal( plnpntsshr[0], plnpntsshr[1], plnpntsshr[2], normal ); VectorSubtract( plnpnts1[2], plnpnts1[1], vec ); if ( DotProduct( vec, normal ) >= 0 ) { newBrushes[0]->AddFace( plnpntsshr[0], plnpntsshr[1], plnpntsshr[2], "textures/common/caulk", true ); } else { newBrushes[0]->AddFace( plnpntsshr[2], plnpntsshr[1], plnpntsshr[0], "textures/common/caulk", true ); } VectorSubtract( plnpnts2[2], plnpnts2[1], vec ); if ( DotProduct( vec, normal ) >= 0 ) { newBrushes[1]->AddFace( plnpntsshr[0], plnpntsshr[1], plnpntsshr[2], "textures/common/caulk", true ); } else { newBrushes[1]->AddFace( plnpntsshr[2], plnpntsshr[1], plnpntsshr[0], "textures/common/caulk", true ); } for ( i = 0; i < 2; i++ ) { newBrushes[i]->RemoveRedundantPlanes(); newBrushes[i]->BuildInRadiant( false, NULL, ents[i] ); delete newBrushes[i]; } }