unsigned int FindPlane( vec3d_t norm, fp_t dist ) { int i; SnapPlane( norm, &dist ); for ( i = 0; i < p_planenum; i++ ) { if ( ArePlanesEqual( p_planes[i].norm, p_planes[i].dist, norm, dist ) ) { aplane_t *pl; pl = (aplane_t *) malloc( sizeof( aplane_t) ); Vec3dCopy( pl->norm, norm ); pl->dist = dist; pl->next = p_planes[i].planes; p_planes[i].planes = pl; return i; } #if 0 else if ( ArePlanesNearlyEqual( p_planes[i].norm, p_planes[i].dist, norm, dist ) ) printf( " * FindPlane: planes are nearly equal. *\n" ); #endif } return AddPlane( norm, dist ); }
void COccluder_2D::InitOutline(const ViewParams& Params, const COccludee::COutline &cOutline, const LTPlane &cPlane) { // Make room m_aEdgePlanes.reserve(cOutline.size()); // Get the plane m_cPolyPlane = cPlane; // Get the reversal flag bool bReverseWinding = false; if (m_cPolyPlane.DistTo(Params.m_Pos) < 0.0f) { m_cPolyPlane = -m_cPolyPlane; bReverseWinding = !bReverseWinding; } m_ePolyPlaneCorner = GetAABBPlaneCorner(m_cPolyPlane.m_Normal); static COccludee::COutline cOutline2D; cOutline2D.clear(); // Read in from the un-transformed occluder LTVector vPrevWorld = cOutline.back(); LTVector vPrevScr; MatVMul_H(&vPrevScr, &Params.m_FullTransform, &vPrevWorld); COccludee::COutline::const_iterator iCurVert = cOutline.begin(); for (; iCurVert != cOutline.end(); ++iCurVert) { const LTVector &vNextWorld = *iCurVert; LTVector vNextScr; MatVMul_H(&vNextScr, &Params.m_FullTransform, &vNextWorld); cOutline2D.push_back(vNextScr); float fXDiff = (vNextScr.x - vPrevScr.x); float fYDiff = (vNextScr.y - vPrevScr.y); if ((fXDiff * fXDiff + fYDiff * fYDiff) > 0.001f) { LTPlane cScreenPlane; LTVector vEdgeScr = vNextScr - vPrevScr; cScreenPlane.m_Normal.Init(vEdgeScr.y, -vEdgeScr.x, 0.0f); cScreenPlane.m_Normal.Normalize(); if (bReverseWinding) cScreenPlane.m_Normal = -cScreenPlane.m_Normal; cScreenPlane.m_Dist = cScreenPlane.m_Normal.x * vNextScr.x + cScreenPlane.m_Normal.y * vNextScr.y; AddPlane(cScreenPlane); } vPrevWorld = vNextWorld; vPrevScr = vNextScr; } // Figure out how big we are on-screen m_fScreenArea = cOutline2D.CalcArea2D(); }
void COccluder_Frustum::InitFrustum(const ViewParams& Params) { // Clear! Init(); // Get the points of the near plane in order const uint32 k_nNumScreenPts = 4; LTVector aScreenPts[k_nNumScreenPts]; aScreenPts[0] = Params.m_ViewPoints[2]; aScreenPts[1] = Params.m_ViewPoints[3]; aScreenPts[2] = Params.m_ViewPoints[1]; aScreenPts[3] = Params.m_ViewPoints[0]; // Gimmie some room m_aEdgePlanes.reserve(k_nNumScreenPts); m_aWorldEdgePlanes.reserve(k_nNumScreenPts); // Remember the near plane m_cPolyPlane = Params.m_ClipPlanes[CPLANE_NEAR_INDEX]; m_ePolyPlaneCorner = GetAABBPlaneCorner(m_cPolyPlane.m_Normal); // Build the occluder LTVector vPrevWorld = aScreenPts[3]; LTVector vPrevScr; MatVMul_H(&vPrevScr, &Params.m_FullTransform, &vPrevWorld); for (const LTVector *pCurVert = aScreenPts; pCurVert != &aScreenPts[k_nNumScreenPts]; ++pCurVert) { const LTVector &vNextWorld = *pCurVert; LTVector vNextScr; MatVMul_H(&vNextScr, &Params.m_FullTransform, &vNextWorld); float fXDiff = (vNextScr.x - vPrevScr.x); float fYDiff = (vNextScr.y - vPrevScr.y); if ((fXDiff * fXDiff + fYDiff * fYDiff) > 0.001f) { LTPlane cScreenPlane; LTVector vEdgeScr = vNextScr - vPrevScr; cScreenPlane.m_Normal.Init(vEdgeScr.y, -vEdgeScr.x, 0.0f); cScreenPlane.m_Normal.Normalize(); cScreenPlane.m_Dist = cScreenPlane.m_Normal.x * vNextScr.x + cScreenPlane.m_Normal.y * vNextScr.y; LTPlane cWorldPlane; LTVector vEdgeWorld = vNextWorld - vPrevWorld; cWorldPlane.m_Normal = vEdgeWorld.Cross(vNextWorld - Params.m_Pos); cWorldPlane.m_Normal.Normalize(); cWorldPlane.m_Dist = cWorldPlane.m_Normal.Dot(vNextWorld); AddPlane(cScreenPlane, cWorldPlane); } vPrevWorld = vNextWorld; vPrevScr = vNextScr; } }
void CurrentApp::AddWidget(PxShape* shape, PxRigidActor* actor, glm::vec4 colour) { PxGeometryType::Enum type = shape->getGeometryType(); switch (type) { case PxGeometryType::eBOX: AddBox(shape, actor, colour); break; case PxGeometryType::ePLANE: AddPlane(shape, actor, glm::vec4(0, 0.4, 0, 1)); break; } }
static void addALine( /*lint -e{818} */ Occluder * pOcc, float x, float y, float z, float x2, float y2, float z2, float x3, float y3, float z3, int otherEdge) { /* Declaring pOcc as constant isn't useful as pointer member is modified (error 818) */ winged_edge we; int planeNum; unsigned int p1 = AddPos(pOcc->handle->points, x, y, z); unsigned int p2 = AddPos(pOcc->handle->points, x2, y2, z2); position pn3; pn3.x = x3; pn3.y = y3; pn3.z = z3; planeNum = (int) AddPlane(pOcc->handle->planes, &g_array_index(pOcc->handle->points, position, p1), &g_array_index(pOcc->handle->points, position, p2), &pn3); we.e[0] = p1; we.e[1] = p2; we.w[0] = planeNum; we.w[1] = otherEdge; /* subsequent attempt to add this edge will replace w[1] */ AddEdge(pOcc->handle->edges, &we); }
uintptr_t CPROC DrawSectorLines( INDEX pSector, uintptr_t unused ) { _POINT o, n; POBJECT object = CreateObject(); INDEX iWorld = DrawThis.iWorld; INDEX pStart, pCur; int count=0; int priorend = unused; DrawThis.object = object; // origin at z +1 scale( o, VectorConst_Y, 10.0 );//SetPoint( o, VectorConst_Z ); // direction z+1 SetPoint( n, VectorConst_Y ); AddPlane( object, o, n, 0 ); Invert( n ); Invert( o ); AddPlane( object, o, n, 0 ); //DrawSpaceLines( display->pImage, pSector->spacenode ); lprintf( WIDE("Adding Sector %d"), pSector ); pCur = pStart = GetFirstWall( iWorld, pSector, &priorend ); do { _POINT tmp; LOGICAL d = IsSectorClockwise( iWorld, pSector ); //GETWORLD( display->pWorld ); INDEX iLine; PFLATLAND_MYLINESEG Line; //VECTOR p1, p2; iLine = GetWallLine( iWorld, pCur ); GetLineData( iWorld, iLine, &Line ); // stop infinite looping... may be badly linked... count++; if( count > 20 ) { xlprintf(LOG_ALWAYS)( WIDE("Conservative limit of 20 lines on a wall has been reached!") ); DebugBreak(); break; } { _POINT o, n, r; //int d; o[0] = Line->r.o[0]; o[1] = Line->r.o[2]; o[2] = Line->r.o[1]; tmp[0] = Line->r.n[0]; tmp[1] = Line->r.n[2]; tmp[2] = Line->r.n[1]; if( priorend ) { lprintf( WIDE("prior end causes reversal...") ); Invert( tmp ); } if( d ) { lprintf( WIDE("Sector clockwise..>") ); Invert( tmp ); } //SetPoint( o, Line->r.o ); crossproduct( n, VectorConst_Y, tmp ); /* if( priorend ) { d = 1; Invert( n ); } else { d = 1; } */ lprintf( WIDE("Adding plane to object... ") ); PrintVector( o ); PrintVector( n ); AddPlane( DrawThis.object, o, n, (GetMatedWall( iWorld, pCur )==INVALID_INDEX)?0:2 ); } pCur = GetNextWall(l.world , pCur, &priorend ); }while( pCur != pStart ); if( IntersectObjectPlanes( object ) ) { // destroy these planes, and add new ones. //priorend = FALSE; //DestroyObject( &object ); } // oh - add lines first one way and then the other... interesting // to test both directions of priorend! if( !unused ) DrawSectorLines( pSector, 1 ); PutIn( object, DrawThis.root ); { PFLATLAND_TEXTURE texture; INDEX iTexture = GetSectorTexture( l.world, pSector ); GetTextureData( l.world, iTexture, &texture ); SetObjectColor( object, texture->data.color /*BASE_COLOR_BLUE*/ ); } return 0; // continue drawing... non zero breaks loop... }
// ===================================================================================== // ClipToSeperators // Source, pass, and target are an ordering of portals. // Generates seperating planes canidates by taking two points from source and one // point from pass, and clips target by them. // If the target argument is NULL, then a list of clipping planes is built in // stack instead. // If target is totally clipped away, that portal can not be seen through. // Normal clip keeps target on the same side as pass, which is correct if the // order goes source, pass, target. If the order goes pass, source, target then // flipclip should be set. // ===================================================================================== inline static winding_t* ClipToSeperators( const winding_t* const source, const winding_t* const pass, winding_t* const a_target, const bool flipclip, pstack_t* const stack) { int i, j, k, l; plane_t plane; vec3_t v1, v2; float d; int counts[3]; bool fliptest; winding_t* target = a_target; const unsigned int numpoints = source->numpoints; // check all combinations for (i=0, l=1; i < numpoints; i++, l++) { if (l == numpoints) { l = 0; } VectorSubtract(source->points[l], source->points[i], v1); // fing a vertex of pass that makes a plane that puts all of the // vertexes of pass on the front side and all of the vertexes of // source on the back side for (j = 0; j < pass->numpoints; j++) { VectorSubtract(pass->points[j], source->points[i], v2); CrossProduct(v1, v2, plane.normal); if (VectorNormalize(plane.normal) < ON_EPSILON) { continue; } plane.dist = DotProduct(pass->points[j], plane.normal); // find out which side of the generated seperating plane has the // source portal fliptest = false; for (k = 0; k < numpoints; k++) { if ((k == i) | (k == l)) // | instead of || for branch optimization { continue; } d = DotProduct(source->points[k], plane.normal) - plane.dist; if (d < -ON_EPSILON) { // source is on the negative side, so we want all // pass and target on the positive side fliptest = false; break; } else if (d > ON_EPSILON) { // source is on the positive side, so we want all // pass and target on the negative side fliptest = true; break; } } if (k == numpoints) { continue; // planar with source portal } // flip the normal if the source portal is backwards if (fliptest) { VectorSubtract(vec3_origin, plane.normal, plane.normal); plane.dist = -plane.dist; } // if all of the pass portal points are now on the positive side, // this is the seperating plane counts[0] = counts[1] = counts[2] = 0; for (k = 0; k < pass->numpoints; k++) { if (k == j) { continue; } d = DotProduct(pass->points[k], plane.normal) - plane.dist; if (d < -ON_EPSILON) { break; } else if (d > ON_EPSILON) { counts[0]++; } else { counts[2]++; } } if (k != pass->numpoints) { continue; // points on negative side, not a seperating plane } if (!counts[0]) { continue; // planar with seperating plane } // flip the normal if we want the back side if (flipclip) { VectorSubtract(vec3_origin, plane.normal, plane.normal); plane.dist = -plane.dist; } if (target != NULL) { // clip target by the seperating plane target = ChopWinding(target, stack, &plane); if (!target) { return NULL; // target is not visible } } else { AddPlane(stack, &plane); } #ifdef RVIS_LEVEL_1 break; /* Antony was here */ #endif } } return target; }
/** * Draw a cube into the verticies buffer. Draws the cube in the x-z plane at * the specified row and column with a set height and color. * * In most cases, the texture coordinates are the same as the offsets for the cube * vertex coordinates. Minor exception for left and right side to ensure texture * is not sideways. * * @param x coordinate location * @param y coordinate location * @param z coordinate location * @param size cube scaling size * @param side cube side to draw * @param type tile type to draw */ void WorldNode::DrawTile(float x, float y, float z, float s, CubeSide side, TileType type) { D3DXVECTOR3 n; // normal switch(side) { case kTop: { D3DXVECTOR3 p1( x, y+s, z ); D3DXVECTOR3 p2( x, y+s, z+s ); D3DXVECTOR3 p3( x+s, y+s, z+s ); D3DXVECTOR3 p4( x+s, y+s, z ); D3DXVec3Cross(&n, &(p2-p1), &(p3-p1)); AddPlane( CustomVertex( p1, n, D3DXVECTOR2(0.0f, 1.0f) ), CustomVertex( p2, n, D3DXVECTOR2(0.0f, 0.0f) ), CustomVertex( p3, n, D3DXVECTOR2(1.0f, 0.0f) ), type); AddPlane( CustomVertex( p1, n, D3DXVECTOR2(0.0f, 1.0f) ), CustomVertex( p3, n, D3DXVECTOR2(1.0f, 0.0f) ), CustomVertex( p4, n, D3DXVECTOR2(1.0f, 1.0f) ), type); m_vCollQuads.push_back( CollQuad(p1, p2, p3, p4, n) ); break; } case kBottom: { D3DXVECTOR3 p1( x, y, z ); D3DXVECTOR3 p2( x, y, z+s ); D3DXVECTOR3 p3( x+s, y, z+s ); D3DXVECTOR3 p4( x+s, y, z ); D3DXVec3Cross(&n, &(p2-p1), &(p3-p1)); AddPlane( CustomVertex( p1, n, D3DXVECTOR2(0.0f, 1.0f) ), CustomVertex( p2, n, D3DXVECTOR2(0.0f, 0.0f) ), CustomVertex( p3, n, D3DXVECTOR2(1.0f, 0.0f) ), type); AddPlane( CustomVertex( p1, n, D3DXVECTOR2(0.0f, 1.0f) ), CustomVertex( p3, n, D3DXVECTOR2(1.0f, 0.0f) ), CustomVertex( p4, n, D3DXVECTOR2(1.0f, 1.0f) ), type); m_vCollQuads.push_back( CollQuad(p1, p2, p3, p4, n) ); break; } case kLeft: { D3DXVECTOR3 p1( x, y, z ); D3DXVECTOR3 p2( x, y, z+s ); D3DXVECTOR3 p3( x, y+s, z+s ); D3DXVECTOR3 p4( x, y+s, z ); D3DXVec3Cross(&n, &(p2-p1), &(p3-p1)); AddPlane( CustomVertex( p1, n, D3DXVECTOR2(1.0f, 1.0f) ), CustomVertex( p2, n, D3DXVECTOR2(0.0f, 1.0f) ), CustomVertex( p3, n, D3DXVECTOR2(0.0f, 0.0f) ), type); AddPlane( CustomVertex( p1, n, D3DXVECTOR2(1.0f, 1.0f) ), CustomVertex( p3, n, D3DXVECTOR2(0.0f, 0.0f) ), CustomVertex( p4, n, D3DXVECTOR2(1.0f, 0.0f) ), type); m_vCollQuads.push_back( CollQuad(p1, p2, p3, p4, n) ); break; } case kRight: { D3DXVECTOR3 p1( x+s, y, z ); D3DXVECTOR3 p2( x+s, y+s, z ); D3DXVECTOR3 p3( x+s, y+s, z+s ); D3DXVECTOR3 p4( x+s, y, z+s ); D3DXVec3Cross(&n, &(p2-p1), &(p3-p1)); AddPlane( CustomVertex( p1, n, D3DXVECTOR2(0.0f, 1.0f) ), CustomVertex( p2, n, D3DXVECTOR2(0.0f, 0.0f) ), CustomVertex( p3, n, D3DXVECTOR2(1.0f, 0.0f) ), type); AddPlane( CustomVertex( p1, n, D3DXVECTOR2(0.0f, 1.0f) ), CustomVertex( p3, n, D3DXVECTOR2(1.0f, 0.0f) ), CustomVertex( p4, n, D3DXVECTOR2(1.0f, 1.0f) ), type); m_vCollQuads.push_back( CollQuad(p1, p2, p3, p4, n) ); break; } case kUpper: { D3DXVECTOR3 p1( x, y, z+s ); D3DXVECTOR3 p2( x+s, y, z+s ); D3DXVECTOR3 p3( x+s, y+s, z+s ); D3DXVECTOR3 p4( x, y+s, z+s ); D3DXVec3Cross(&n, &(p2-p1), &(p3-p1)); AddPlane( CustomVertex( p1, n, D3DXVECTOR2(1.0f, 1.0f) ), CustomVertex( p2, n, D3DXVECTOR2(0.0f, 1.0f) ), CustomVertex( p3, n, D3DXVECTOR2(0.0f, 0.0f) ), type); AddPlane( CustomVertex( p1, n, D3DXVECTOR2(1.0f, 1.0f) ), CustomVertex( p3, n, D3DXVECTOR2(0.0f, 0.0f) ), CustomVertex( p4, n, D3DXVECTOR2(1.0f, 0.0f) ), type); m_vCollQuads.push_back( CollQuad(p1, p2, p3, p4, n) ); break; } case kLower: { D3DXVECTOR3 p1( x, y, z ); D3DXVECTOR3 p2( x, y+s, z ); D3DXVECTOR3 p3( x+s, y+s, z ); D3DXVECTOR3 p4( x+s, y, z ); D3DXVec3Cross(&n, &(p2-p1), &(p3-p1)); AddPlane( CustomVertex( p1, n, D3DXVECTOR2(0.0f, 1.0f) ), CustomVertex( p2, n, D3DXVECTOR2(0.0f, 0.0f) ), CustomVertex( p3, n, D3DXVECTOR2(1.0f, 0.0f) ), type); AddPlane( CustomVertex( p1, n, D3DXVECTOR2(0.0f, 1.0f) ), CustomVertex( p3, n, D3DXVECTOR2(1.0f, 0.0f) ), CustomVertex( p4, n, D3DXVECTOR2(1.0f, 1.0f) ), type); m_vCollQuads.push_back( CollQuad(p1, p2, p3, p4, n) ); break; } default: break; } }
//--------------------------------------------------------------- void Tracker::AddTrackerConeVerts(ovrSession Session, Model* m, bool isItEdges) { //Get attributes of camera cone std::vector<ovrTrackerDesc> TrackerDescArray; unsigned int trackerCount = std::max<unsigned int>(1, ovr_GetTrackerCount(Session)); // Make sure there's always at least one. for (unsigned int i = 0; i < trackerCount; ++i) TrackerDescArray.push_back(ovr_GetTrackerDesc(Session, i)); // v4-------v5 float hFOV = TrackerDescArray[0].FrustumHFovInRadians; // | \ / | float vFOV = TrackerDescArray[0].FrustumVFovInRadians; // | v0-v1 | float nearZ = TrackerDescArray[0].FrustumNearZInMeters; // | | C | | float farZ = TrackerDescArray[0].FrustumFarZInMeters; // | v2-v3 | // | / \ | // v6-------v7 // MA: Having the lines/pyramid start closer to camera looks better. nearZ = 0.08f; Vector3f baseVec3(tan(0.5f * hFOV), tan(0.5f * vFOV), 1.0f); v[0] = v[4] = Vector3f(baseVec3.x, -baseVec3.y, 1.0f); v[1] = v[5] = Vector3f(-baseVec3.x, -baseVec3.y, 1.0f); v[2] = v[6] = Vector3f(baseVec3.x, baseVec3.y, 1.0f); v[3] = v[7] = Vector3f(-baseVec3.x, baseVec3.y, 1.0f); v[8] = Vector3f(0, 0, 0.5f*lengthOfTrackerHead); //front of tracker location // Project to near and far planes for (int i = 0; i < 8; i++) { float depth = (i < 4 ? nearZ : farZ); v[i].x *= depth; v[i].y *= depth; v[i].z *= depth; } Color c = Color(255, 255, 255, 255); if (isItEdges) //Wire parts { #define AddEdge(i0,i1) m->AddQuad( \ Vertex(v[i0],c,0,0),Vertex(v[i1],c,0,0), \ Vertex(v[i1], c, 0, 0), Vertex(v[i1], c, 0, 0)); if (drawWalls) { // Add wireframe fronty and back outlines if we have walls AddEdge(0, 1); AddEdge(1, 3); AddEdge(3, 2); AddEdge(2, 0); AddEdge(4, 5); AddEdge(5, 7); AddEdge(7, 6); AddEdge(6, 4); } AddEdge(4, 0); AddEdge(5, 1); AddEdge(7, 3); AddEdge(6, 2); if (extendLinesToTracker) { AddEdge(8, 0); AddEdge(8, 1); AddEdge(8, 2); AddEdge(8, 3); } } else //Solid planes { float gridDensity = 6.0f; #define AddPlane(i0,i1,i2,i3,U,V,dense) m->AddQuad( \ Vertex(v[i0], c, dense*v[i0].U, dense*v[i0].V), \ Vertex(v[i1], c, dense*v[i1].U, dense*v[i1].V), \ Vertex(v[i2], c, dense*v[i2].U, dense*v[i2].V), \ Vertex(v[i3], c, dense*v[i3].U, dense*v[i3].V)) AddPlane(4, 0, 6, 2, z, y, gridDensity); // Left AddPlane(1, 5, 3, 7, z, y, gridDensity); // Right AddPlane(4, 5, 0, 1, x, z, gridDensity); // Top AddPlane(2, 3, 6, 7, x, z, gridDensity); // Bot AddPlane(5, 4, 7, 6, x, y, gridDensity); // Back if (frontOfGridAsWell) { AddPlane(0, 1, 2, 3, x, y, gridDensity); } // Front } }
void Frustum::CalculateFrustum(float angle, float ratio, float near, float far, Vector3D &camPos, Vector3D &lookAt, Vector3D &up) { Vector3D xVec, yVec, zVec; Vector3D vecN, vecF; Vector3D nearTopLeft, nearTopRight, nearBottomLeft, nearBottomRight; Vector3D farTopLeft, farTopRight, farBottomLeft, farBottomRight; float radians = (float)tan((DEG_TO_RAD(angle)) * 0.5); float nearH = near * radians; float nearW = nearH * ratio; float farH = far * radians; float farW = farH * ratio; zVec = camPos - lookAt; zVec.Normalize(); xVec = up.CrossProduct(zVec); xVec.Normalize(); yVec = zVec.CrossProduct(xVec); vecN = camPos - zVec * near; vecF = camPos - zVec * far; nearTopLeft = vecN + yVec * nearH - xVec * nearW; nearTopRight = vecN + yVec * nearH + xVec * nearW; nearBottomLeft = vecN - yVec * nearH - xVec * nearW; nearBottomRight = vecN - yVec * nearH + xVec * nearW; farTopLeft = vecF + yVec * farH - xVec * farW; farTopRight = vecF + yVec * farH + xVec * farW; farBottomLeft = vecF - yVec * farH - xVec * farW; farBottomRight = vecF - yVec * farH + xVec * farW; m_frustum.clear(); Plane plane; plane.CreatePlaneFromTri(nearTopRight, nearTopLeft, farTopLeft); AddPlane(plane); plane.CreatePlaneFromTri(nearBottomLeft, nearBottomRight, farBottomRight); AddPlane(plane); plane.CreatePlaneFromTri(nearTopLeft, nearBottomLeft, farBottomLeft); AddPlane(plane); plane.CreatePlaneFromTri(nearBottomRight, nearTopRight, farBottomRight); AddPlane(plane); plane.CreatePlaneFromTri(nearTopLeft, nearTopRight, nearBottomRight); AddPlane(plane); plane.CreatePlaneFromTri(farTopRight, farTopLeft, farBottomLeft); AddPlane(plane); }