void LFrustum::CreateFrustum( const LMatrix4& Projection, const LMatrix4& ModelView ) { LMatrix4 ProjModelView = ModelView * Projection; for ( int i = 0; i != 4; ++i ) { FPlanes[0][i] = ProjModelView[i][3] + ProjModelView[i][0]; // left FPlanes[1][i] = ProjModelView[i][3] - ProjModelView[i][0]; // right FPlanes[2][i] = ProjModelView[i][3] - ProjModelView[i][1]; // top FPlanes[3][i] = ProjModelView[i][3] + ProjModelView[i][1]; // bottom FPlanes[4][i] = ProjModelView[i][3] + ProjModelView[i][2]; // near FPlanes[5][i] = ProjModelView[i][3] - ProjModelView[i][2]; // far } for ( int i = 0; i != 6; ++i ) { LVector3 Vec = FPlanes[i].ToVector3(); float Len = Vec.Length(); if ( Len > Linderdaum::Math::EPSILON ) { FPlanes[i] /= Len; } } }
// (Re)generate representing geometry (beads and sticks) for the graph/curve clGeom* clGraph::CreateGraphGeometry( float BeadRadius, float TubeRadius, float EdgeArrowSize, bool UseCubes, clMaterial* BeadMaterial, clMaterial* StickMaterial, clMaterial* EdgeArrowMaterial ) { clMesh* Mesh = Env->Resources->CreateMesh(); int VtxMaterialID = Mesh->AddMaterial( BeadMaterial->GetMaterialDesc() ); // 1. points(vertices) are spheres for ( size_t i = 0 ; i < FVertices.size() ; i++ ) { // int VtxGeomID = static_cast<int>(i); clVertexAttribs* VtxVA; LVector3 BoxMin( -BeadRadius, -BeadRadius, -BeadRadius ); LVector3 BoxMax( +BeadRadius, +BeadRadius, +BeadRadius ); // name it for picking LString VtxName = LString( "Vertex " ) + LStr::ToStr( i ); if ( UseCubes ) { FIXME( "hack, resources should also create a VA ? Or it is a geomserv ?" ) // clGeomServ::CreateAxisAlignedBox(BoxMin, BoxMax, false); VtxVA = Env->Resources->CreateBox( BoxMin, BoxMax )->GetCurrentMesh()->GetRigid( 0 ); } else { // it does not work... // VtxVA = Env->Resources->CreateSphere(); VtxVA = Env->Resources->CreateBox( BoxMin, BoxMax )->GetCurrentMesh()->GetRigid( 0 ); } LVector3 VtxPos = FVertices[i]; LMatrix4 VtxTransform = LMatrix4::GetTranslateMatrix( VtxPos ); if ( UseCubes ) { LQuaternion VtxOrientation = FLocalOrientations[i]; // orient the cube at point, if needed VtxTransform = ComposeTransformation( VtxPos, LMatrix4( VtxOrientation.ToMatrix3() ) ); // add rotation from LocalOrientation } Mesh->AddVertexAttribs( VtxName, VtxVA, VtxTransform, -1, VtxMaterialID ); } // 2. render arrows for oriented edges int ArrowMaterialID = -1; if ( FOriented && EdgeArrowMaterial ) { ArrowMaterialID = Mesh->AddMaterial( EdgeArrowMaterial->GetMaterialDesc() ); } // map< pair<int,int> > ProcessedEdges; int EdgeMaterialID = Mesh->AddMaterial( StickMaterial->GetMaterialDesc() ); // 3. render lines from point to point ("tubes"), avoiding duplicate generation for non-oriented edges for ( size_t i = 0; i < FEdge0.size() ; i++ ) { int v1 = FEdge0[i]; int v2 = FEdge1[i]; LVector3 v1pos = FVertices[v1]; LVector3 v2pos = FVertices[v2]; LVector3 Dir = ( v2pos - v1pos ); LVector3 DirN = Dir.GetNormalized(); LVector3 EndPointDir = -Dir.Length() * DirN * ( EdgeArrowSize ); LVector3 Offset = DirN * EdgeArrowSize; clVertexAttribs* EdgeVA = clGeomServ::CreateTube( 10, v1pos + Offset, Dir - Offset, TubeRadius, false ); // name the edge for picking LString EdgeName = LString( "Edge " ) + LStr::ToStr( v1 ) + LString( " " ) + LStr::ToStr( v2 ); LMatrix4 EdgeTransform = LMatrix4::Identity(); Mesh->AddVertexAttribs( EdgeName, EdgeVA, EdgeTransform, -1, EdgeMaterialID ); FIXME( "avoid duplicates, use processed edges list" ) // add arrow, if required if ( FOriented ) { clVertexAttribs* ArrowVA = clGeomServ::CreateTube( 10, v2pos - Offset, -EndPointDir, TubeRadius * 2.0f , true ); LString ArrowName = LString( "Arrow_" ) + EdgeName; LMatrix4 ArrowTransform = LMatrix4::Identity(); Mesh->AddVertexAttribs( ArrowName, ArrowVA, ArrowTransform, -1, ArrowMaterialID ); } } clGeom* Geom = Env->Resources->CreateGeom(); Geom->SetMesh( Mesh ); return Geom; }