Пример #1
0
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;
}
Пример #2
0
 const std::vector<T>& vec() const {
     if (m_A)
         return vecA();
     else if (m_B)
         return vecB();
     else
         return vecC();
 }
Пример #3
0
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);
		}
		*/

	}

}