bool MFCollision_SweepSphereTriTest(const MFVector &sweepSpherePos, const MFVector &sweepSphereVelocity, float sweepSphereRadius, const MFCollisionTriangle &tri, MFSweepSphereResult *pResult) { MFRayIntersectionResult result; // test the triangle surface if(!MFCollision_RaySlabTest(sweepSpherePos, sweepSphereVelocity, tri.plane, sweepSphereRadius, &result)) return false; MFVector intersection = sweepSpherePos + sweepSphereVelocity * result.time; // test if intersection is inside the triangle float dot0, dot1, dot2; dot0 = intersection.DotH(tri.edgePlanes[0]); // if(dot0 > sphereRadius) // return false; dot1 = intersection.DotH(tri.edgePlanes[1]); // if(dot1 > sphereRadius) // return false; dot2 = intersection.DotH(tri.edgePlanes[2]); // if(dot2 > sphereRadius) // return false; // test if intersection is inside the triangle face if(dot0 >= 0.0f && dot1 >= 0.0f && dot2 >= 0.0f) goto collision; // test the 3 edges if(dot0 < 0.0f) { if(MFCollision_RayCapsuleTest(sweepSpherePos, sweepSphereVelocity, tri.verts[0], tri.verts[1]-tri.verts[0], sweepSphereRadius, &result)) goto collision; } if(dot1 < 0.0f) { if(MFCollision_RayCapsuleTest(sweepSpherePos, sweepSphereVelocity, tri.verts[1], tri.verts[2]-tri.verts[1], sweepSphereRadius, &result)) goto collision; } if(dot2 < 0.0f) { if(MFCollision_RayCapsuleTest(sweepSpherePos, sweepSphereVelocity, tri.verts[2], tri.verts[0]-tri.verts[2], sweepSphereRadius, &result)) goto collision; } return false; collision: if(result.time == 0.0f) { // this is for double sided collision. float dot = sweepSpherePos.DotH(tri.plane); float amountResolve = sweepSphereRadius - MFAbs(dot); pResult->intersectionReaction = result.surfaceNormal * amountResolve; } else pResult->intersectionReaction = MFVector::zero; pResult->surfaceNormal = result.surfaceNormal; pResult->time = result.time; return true; }
void Menu::Draw() { MFVector dimensions = MakeVector(0.0f, 0.0f, 0.0f); MFVector currentPos; float requestedWidth = menuDimensions.x-40.0f; float selStart, selEnd; int a; // get menu size for(a=0; a<numChildren; a++) { MFVector dim = pChildren[a]->GetDimensions(requestedWidth); if(selection==a) { selStart = dimensions.y; selEnd = selStart + dim.y; if(selStart < -yOffset) { targetOffset = -selStart; } if(selEnd > menuDimensions.y - 75.0f - yOffset) { targetOffset = -(selEnd-(menuDimensions.y-75.0f)); } } dimensions.y += dim.y; dimensions.x = MFMax(dimensions.x, dim.x); } if(targetOffset != yOffset) { yOffset -= MFAbs(yOffset-targetOffset) < 0.1f ? yOffset-targetOffset : (yOffset-targetOffset)*0.1f; } currentPos = MakeVector(menuPosition.x+20.0f, menuPosition.y+50.0f + yOffset, 0.0f); MFPrimitive(PT_TriStrip|PT_Untextured); MFBegin(4); MFSetColourV(colour*0.4f); MFSetPosition(menuPosition.x, menuPosition.y, 0); MFSetColourV(colour*0.8f); MFSetPosition(menuPosition.x+menuDimensions.x, menuPosition.y, 0); MFSetColourV(colour*0.6f); MFSetPosition(menuPosition.x, menuPosition.y+menuDimensions.y, 0); MFSetColourV(colour); MFSetPosition(menuPosition.x+menuDimensions.x, menuPosition.y+menuDimensions.y, 0); MFEnd(); MFFont_DrawText2(MFFont_GetDebugFont(), menuPosition.x+10.0f, menuPosition.y+5.0f, MENU_FONT_HEIGHT*1.5f, MakeVector(1,0.6875f,0.5f,1), name); MFMaterial_SetMaterial(MFMaterial_GetStockMaterial(MFMat_SysLogoSmall)); float logoMargin = 5.0f; float iconSize = 35.0f; MFPrimitive(PT_TriStrip); MFBegin(4); MFSetColourV(MFVector::white); MFSetTexCoord1(0,0); MFSetPosition((menuPosition.x+menuDimensions.x) - logoMargin*2 - iconSize, menuPosition.y + logoMargin, 0); MFSetTexCoord1(1,0); MFSetPosition((menuPosition.x+menuDimensions.x) - logoMargin*2, menuPosition.y + logoMargin, 0); MFSetTexCoord1(0,1); MFSetPosition((menuPosition.x+menuDimensions.x) - logoMargin*2 - iconSize, menuPosition.y + logoMargin + iconSize, 0); MFSetTexCoord1(1,1); MFSetPosition((menuPosition.x+menuDimensions.x) - logoMargin*2, menuPosition.y + logoMargin + iconSize, 0); MFEnd(); #if MF_RENDERER == MF_DRIVER_D3D9 || MF_RENDERER == MF_DRIVER_XBOX pd3dDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE); pd3dDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); pd3dDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCR); #endif MFPrimitive(PT_TriStrip|PT_Untextured); MFBegin(4); MFSetColour(0.f, 0.f, 0.f, 0.65f); MFSetPosition(menuPosition.x+15, menuPosition.y+45, 0); MFSetPosition(menuPosition.x+menuDimensions.x-15, menuPosition.y+45, 0); MFSetPosition(menuPosition.x+15, menuPosition.y+menuDimensions.y-15, 0); MFSetPosition(menuPosition.x+menuDimensions.x-15, menuPosition.y+menuDimensions.y-15, 0); MFEnd(); #if MF_RENDERER == MF_DRIVER_D3D9 || MF_RENDERER == MF_DRIVER_XBOX pd3dDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_LESS); pd3dDevice->SetRenderState(D3DRS_STENCILREF, 0); #endif for(a=0; a<numChildren; a++) { if(currentPos.y > menuPosition.y + menuDimensions.y - 15.0f) break; if(selection==a) { float height = pChildren[a]->GetDimensions(requestedWidth).y; if(currentPos.y + height < menuPosition.y + 45.0f) { currentPos.y += height; continue; } MFPrimitive(PT_TriStrip|PT_Untextured); MFBegin(4); MFSetColour(0.f, 0.f, .5f, .75f); MFSetPosition(menuPosition.x+15, currentPos.y, 0); MFSetColour(0.f, 0.f, .8f, .75f); MFSetPosition(menuPosition.x+menuDimensions.x-15, currentPos.y, 0); MFSetColour(0.f, 0.f, .56f, .75f); MFSetPosition(menuPosition.x+15, currentPos.y + height, 0); MFSetColour(0.f, 0.f, .1f, .75f); MFSetPosition(menuPosition.x+menuDimensions.x-15, currentPos.y + height, 0); MFEnd(); } currentPos.y += pChildren[a]->ListDraw(selection==a, currentPos, requestedWidth); } #if MF_RENDERER == MF_DRIVER_D3D9 || MF_RENDERER == MF_DRIVER_XBOX pd3dDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); #endif }