static int get_lattice_from_ts(Lattice *lattice, const molfile_timestep_t *ts) { // Check if valid unit cell data is contained in the timestep. We don't // have any formalized way of doing this yet; for now, just check that // the length of the vector is greater than 1. if (ts->A <= 1 || ts->B <= 1 || ts->C <= 1) return 0; // convert from degrees to radians // Try to get exact results when the angles are exactly 90. double epsalpha = DEG2RAD*(ts->alpha-90.0); double epsbeta = DEG2RAD*(ts->beta-90.0); double epsgamma = DEG2RAD*(ts->gamma-90.0); double cosAB = -sin(epsgamma); double sinAB = cos(epsgamma); double cosAC = -sin(epsbeta); double cosBC = -sin(epsalpha); // A will lie along the positive x axis. // B will lie in the x-y plane // The origin will be (0,0,0). Vector A(0), B(0), vecC(0); A.x = ts->A; B.x = ts->B*cosAB; B.y = ts->B*sinAB; //if (fabs(B.x) < UNITCELLSLOP) B.x = 0; //if (fabs(B.y) < UNITCELLSLOP) B.y = 0; vecC.x = ts->C * cosAC; vecC.y = (ts->B*ts->C*cosBC - B.x*vecC.x)/B.y; vecC.z = sqrt(ts->C*ts->C - vecC.x*vecC.x - vecC.y*vecC.y); //if (fabs(vecC.x) < UNITCELLSLOP) vecC.x = 0; //if (fabs(vecC.y) < UNITCELLSLOP) vecC.y = 0; //if (fabs(vecC.z) < UNITCELLSLOP) vecC.z = 0; lattice->set(A, B, vecC, Vector(0)); return 1; }
const std::vector<T>& vec() const { if (m_A) return vecA(); else if (m_B) return vecB(); else return vecC(); }
void SceneManager::Update() { RenderLayerManager & renderManager = RenderLayerManager::GetRenderLayerManager(); const PVRTVec3 center = renderManager.GetCenter(); float occlusionRadius = renderManager.GetOcclusionRadius(); PVRTVec4 vecA( mLookMtx->f[12], 0.0f, mLookMtx->f[14], 1); PVRTVec4 vecB( GLOBAL_SCALE * FRUSTUM_W, 0.0f, GLOBAL_SCALE * FRUSTUM_D, 1); PVRTVec4 vecC( GLOBAL_SCALE * -FRUSTUM_W, 0.0f, GLOBAL_SCALE * FRUSTUM_D, 1); vecB = *mLookMtx * vecB; vecC = *mLookMtx * vecC; PVRTVec2 A(vecA.x, vecA.z); PVRTVec2 B(vecB.x, vecB.z); PVRTVec2 C(vecC.x, vecC.z); mToApplyCount = 0; if (mQuadTree) { static QuadNode * quadNodes[256]={0}; int quadNodeCount = 0; //mQuadTree->GetQuads(center.x, center.z, occlusionRadius, quadNodes, quadNodeCount); mQuadTree->GetQuadsCameraFrustum(quadNodes, quadNodeCount, mLookMtx); quadNodeCount--; bool useFrustumCulling = true; //!!!!!!!!!!!!!!!!!!!!! for (int quad = quadNodeCount ; quad >=0 ; quad--) { QuadNode * pQuadNode = quadNodes[quad]; List & dataList = pQuadNode->GetDataList(); ListIterator listIter(dataList); while( Node * pRootNode = (Node*)listIter.GetPtr() ) { if (!pRootNode->IsVisible()) continue; //pRootNode->UpdateWithoutChildren(); bool useOcclusionRadius = pRootNode->GetUseOcclusionCulling(); PVRTVec3 worldPos = pRootNode->GetWorldTranslation(); if (!useFrustumCulling && useOcclusionRadius) { PVRTVec3 distVec = worldPos - center; if ( distVec.lenSqr() < MM(occlusionRadius) ) { pRootNode->SetInFrustum(true); pRootNode->Update(); mToApply[mToApplyCount] = pRootNode; mToApplyCount++; } else { pRootNode->SetInFrustum(false); } } else if (useFrustumCulling) { PVRTVec2 P(worldPos.x, worldPos.z); PVRTVec2 v0 = C - A; PVRTVec2 v1 = B - A; PVRTVec2 v2 = P - A; // Compute dot products float dot00 = v0.dot(v0); float dot01 = v0.dot(v1); float dot02 = v0.dot(v2); float dot11 = v1.dot(v1); float dot12 = v1.dot(v2); // Compute barycentric coordinates float invDenom = 1.0f / (dot00 * dot11 - dot01 * dot01); float u = (dot11 * dot02 - dot01 * dot12) * invDenom; float v = (dot00 * dot12 - dot01 * dot02) * invDenom; bool addToList = false; // Check if point is in triangle //PVRTVec3 distVec = worldPos - center; //if ( distVec.lenSqr() < MM(occlusionRadius) ) { if ( (u > 0) && (v > 0) && (u + v < 1)) { addToList = true; } else if ( Collision::CircleTriangleEdgeIntersection(A,B,P, pRootNode->GetRadius() ) ) { addToList = true; } else if ( Collision::CircleTriangleEdgeIntersection(A,C,P, pRootNode->GetRadius() )) { addToList = true; } if (addToList) { pRootNode->SetInFrustum(true); //pRootNode->Update(); mToApply[mToApplyCount] = pRootNode; mToApplyCount++; } else { pRootNode->SetInFrustum(false); } } //else //{ // pRootNode->SetInFrustum(false); //} } else { pRootNode->SetInFrustum(true); //pRootNode->Update(); mToApply[mToApplyCount] = pRootNode; mToApplyCount++; } } } } for (int n=0;n<mNodeCount;n++) { Node * pRootNode = mRootNodes[n]; if (!pRootNode->IsVisible()) continue; pRootNode->UpdateWithoutChildren(); bool useOcclusionRadius = pRootNode->GetUseOcclusionCulling(); PVRTVec3 worldPos = pRootNode->GetWorldTranslation(); PVRTVec3 distVec = worldPos - center; if (useOcclusionRadius) { if ( distVec.lenSqr() < MM(occlusionRadius) ) { PVRTVec2 P(worldPos.x, worldPos.z); PVRTVec2 v0 = C - A; PVRTVec2 v1 = B - A; PVRTVec2 v2 = P - A; // Compute dot products float dot00 = v0.dot(v0); float dot01 = v0.dot(v1); float dot02 = v0.dot(v2); float dot11 = v1.dot(v1); float dot12 = v1.dot(v2); // Compute barycentric coordinates float invDenom = 1.0f / (dot00 * dot11 - dot01 * dot01); float u = (dot11 * dot02 - dot01 * dot12) * invDenom; float v = (dot00 * dot12 - dot01 * dot02) * invDenom; bool addToList = false; // Check if point is in triangle //PVRTVec3 distVec = worldPos - center; //if ( distVec.lenSqr() < MM(occlusionRadius) ) { if ( (u > 0) && (v > 0) && (u + v < 1)) { addToList = true; } else if ( Collision::CircleTriangleEdgeIntersection(A,B,P, pRootNode->GetRadius() ) ) { addToList = true; } else if ( Collision::CircleTriangleEdgeIntersection(A,C,P, pRootNode->GetRadius() )) { addToList = true; } if (addToList) { pRootNode->SetInFrustum(true); pRootNode->Update(); mToApply[mToApplyCount] = pRootNode; mToApplyCount++; } else { pRootNode->SetInFrustum(false); } } /* pRootNode->SetInFrustum(true); pRootNode->Update(); mToApply[mToApplyCount] = pRootNode; mToApplyCount++; */ } else { pRootNode->SetInFrustum(false); } } else { pRootNode->SetInFrustum(true); pRootNode->Update(); mToApply[mToApplyCount] = pRootNode; mToApplyCount++; } /* PVRTVec3 worldPos = pRootNode->GetWorldTranslation(); PVRTVec3 distVec = worldPos - center; if (!pRootNode->GetUseOcclusionCulling()) { pRootNode->SetInFrustum(true); } else if ( distVec.lenSqr() < occlusionRadius ) { pRootNode->SetInFrustum(true); } else { pRootNode->SetInFrustum(false); } */ } }