Esempio n. 1
0
CoriolisEvaluate (Coriolis *inst, LWTextureAccess *ta)
{
  /* Local stuff */
  double  rsq, angle, value, sine, cosine, turb;

  /* Position Stuff */
  double  Pt[3], PtN[3], PP[3];

  // Lets work in shader space
  if (ta->axis == 0) {
	 Vec3Assign(Pt, ta->tPos[2], -ta->tPos[1], ta->tPos[0]);
  } else if (ta->axis == 1) {
	 Vec3Assign(Pt, ta->tPos[0], -ta->tPos[2], ta->tPos[1]);
  } else {
		Vec3Assign(Pt, ta->tPos[0], -ta->tPos[1], ta->tPos[2]);
  }

  Vec3Copy(PtN, Pt);
  normalize3(PtN);
	
  rsq = xcomp(PtN) * xcomp(PtN) + ycomp(PtN) * ycomp(PtN);

  angle = inst->tws[0] * rsq;

  sine   = sin( angle );
  cosine = cos( angle );
  PP[0] = Pt[0]*cosine - Pt[1]*sine;
  PP[1] = Pt[0]*sine + Pt[1]*cosine;
  PP[2] = Pt[2];

  turb = fBm(PP, inst->inc[0], inst->lac[0], inst->oct[0], inst->fnoise);
  value = Abs(inst->off[0] + inst->scl[0] * turb);
  value = clamp(value, 0, 1);

  return value;
}
	//
	// 更新
	//
	VOID CGfxBillboard::Update(const CEntityCamera *pCamera, CParticle *pParticleList, INT numParticles)
	{
		//
		// 1. 参数安全检查
		//
		if (pCamera == NULL || pParticleList == NULL || numParticles <= 0) {
			return;
		}

		//
		// 2. 更新相机矩阵
		//
		if (m_directionType == DIRECTION_CAMERA) {
			VEC3 direction;
			VEC3 position, up, target;

			Vec3Scale(&direction, pCamera->GetForwardDirection(), -1.0f);
			Vec3Set(&up, 0.0f, 1.0f, 0.0f);
			Vec3Set(&position, 0.0f, 0.0f, 0.0f);
			Vec3Ma(&target, &position, &direction, 1.0f);

			MtxDefLookAt(&m_mtxFaceToCamera, &position, &up, &target);
		}

		//
		// 3. 更新粒子数据
		//
		VERTEX *vertices = (VERTEX *)SAFE_MALLOC(4 * numParticles * sizeof(*vertices), MEMTYPE_STACK);
		{
			//    Billboard
			//    0 ___ 3
			//     |   |
			//     |___|
			//    1     2

			INT indexVertex = 0;
			CParticle *pParticle = pParticleList;

			while (pParticle) {
				const VEC3 *parentWorldScale = pParticle->pEmitter->GetWorldScale();
				const VEC3 *parentWorldPosition = pParticle->pEmitter->GetWorldPosition();
				const QUAT *parentWorldOrientation = pParticle->pEmitter->GetWorldOrientation();

				//
				// 1. 计算粒子位置与朝向
				//
				VEC3 scale;
				VEC3 position;
				QUAT orientation;

				if (pParticle->bKeepLocal && pParticle->pEmitter) {
					Vec3Mul(&scale, &pParticle->localScale, parentWorldScale);

					if (m_directionType == DIRECTION_FIXED) {
						QuatMul(&orientation, &pParticle->localOrientation, parentWorldOrientation);
					}

					VEC3 scalePosition;
					VEC3 scaleOrientationPosition;
					Vec3Mul(&scalePosition, &pParticle->localPosition, parentWorldScale);
					Vec3MulQuat(&scaleOrientationPosition, &scalePosition, parentWorldOrientation);
					Vec3Add(&position, &scaleOrientationPosition, parentWorldPosition);
				}
				else {
					Vec3Copy(&scale, &pParticle->localScale);

					if (m_directionType == DIRECTION_FIXED) {
						QuatCopy(&orientation, &pParticle->localOrientation);
					}

					Vec3Copy(&position, &pParticle->localPosition);
				}

				//
				// 2. 粒子位置偏移量
				//
				MATRIX4 mtxOrientation;

				if (m_directionType == DIRECTION_CAMERA) {
					MtxCopy(&mtxOrientation, &m_mtxFaceToCamera);

					if (m_offset < -EPSILON_E3 || m_offset > EPSILON_E3) {
						VEC3 offsetDirection;
						Vec3Sub(&offsetDirection, pCamera->GetPosition(), &position);
						Vec3Normalize(&offsetDirection);
						Vec3Ma(&position, &position, &offsetDirection, m_offset);
					}
				}
				else {
					QuatToMtxRotation(&mtxOrientation, &orientation);

					if (m_offset < -EPSILON_E3 || m_offset > EPSILON_E3) {
						VEC3 localDirection;
						VEC3 offsetDirection;
						Vec3Set(&localDirection, 0.0f, 0.0f, 1.0f);
						Vec3MulQuat(&offsetDirection, &localDirection, &orientation);
						Vec3Normalize(&offsetDirection);
						Vec3Ma(&position, &position, &offsetDirection, m_offset);
					}
				}

				//
				// 3. 计算粒子变换矩阵
				//
				MATRIX4 mtxScale;
				MATRIX4 mtxRotate;
				MATRIX4 mtxRotateSelf;
				MATRIX4 mtxTranslate;
				MtxDefScale(&mtxScale, scale[0], scale[1], scale[2]);
				MtxDefTranslate(&mtxTranslate, position[0], position[1], position[2]);
				MtxDefRotateAxisAngle(&mtxRotateSelf, &axisz, pParticle->radian);
				MtxMul(&mtxRotate, &mtxRotateSelf, &mtxOrientation);

				MATRIX4 mtxSR;
				MATRIX4 mtxTransform;
				MtxMul(&mtxSR, &mtxScale, &mtxRotate);
				MtxMul(&mtxTransform, &mtxSR, &mtxTranslate);

				//
				// 4. 计算粒子纹理矩阵
				//
				MATRIX4 mtxTexScale;
				MATRIX4 mtxTexTranslate;
				MATRIX4 mtxTexTransform;
				MtxDefScale(&mtxTexScale, pParticle->texSequenceScale[0], pParticle->texSequenceScale[1], 1.0f);
				MtxDefTranslate(&mtxTexTranslate, pParticle->texSequenceOffset[0] + pParticle->texScrollOffset[0], pParticle->texSequenceOffset[1] + pParticle->texScrollOffset[1], 0.0f);
				MtxMul(&mtxTexTransform, &mtxTexScale, &mtxTexTranslate);

				//
				// 5. 计算粒子顶点
				//
				VEC3 desVertices[4];
				VEC3 srcVertices[4] = {
					VEC3(-1.0f,  1.0f, 0.0f),
					VEC3(-1.0f, -1.0f, 0.0f),
					VEC3( 1.0f, -1.0f, 0.0f),
					VEC3( 1.0f,  1.0f, 0.0f),
				};

				VEC2 texCoords[4] = {
					VEC2(pParticle->uvOffset[0] + 0.0f, pParticle->uvOffset[1] + 0.0f),
					VEC2(pParticle->uvOffset[0] + 0.0f, pParticle->uvOffset[1] + 1.0f),
					VEC2(pParticle->uvOffset[0] + 1.0f, pParticle->uvOffset[1] + 1.0f),
					VEC2(pParticle->uvOffset[0] + 1.0f, pParticle->uvOffset[1] + 0.0f),
				};

				VEC3 localNormal, localBinormal;
				VEC3 worldNormal, worldBinormal;

				Vec3Set(&localNormal, 0.0f, 0.0f, 1.0f);
				Vec3Set(&localBinormal, 1.0f, 0.0f, 0.0f);
				Vec3MulMtx3x3(&worldNormal, &localNormal, &mtxTransform);
				Vec3MulMtx3x3(&worldBinormal, &localBinormal, &mtxTransform);

				Vec3MulMtx4x4(&desVertices[0], &srcVertices[0], &mtxTransform);
				Vec3MulMtx4x4(&desVertices[1], &srcVertices[1], &mtxTransform);
				Vec3MulMtx4x4(&desVertices[2], &srcVertices[2], &mtxTransform);
				Vec3MulMtx4x4(&desVertices[3], &srcVertices[3], &mtxTransform);

				Vec3Copy(&vertices[indexVertex].position, &desVertices[0]);
				Vec3Copy(&vertices[indexVertex].normal, &worldNormal);
				Vec3Copy(&vertices[indexVertex].binormal, &worldBinormal);
				Vec4Copy(&vertices[indexVertex].color, &pParticle->color);
				Vec2MulMtx4x4(&vertices[indexVertex].texCoordDiffuse, &texCoords[0], &mtxTexTransform);
				indexVertex++;

				Vec3Copy(&vertices[indexVertex].position, &desVertices[1]);
				Vec3Copy(&vertices[indexVertex].normal, &worldNormal);
				Vec3Copy(&vertices[indexVertex].binormal, &worldBinormal);
				Vec4Copy(&vertices[indexVertex].color, &pParticle->color);
				Vec2MulMtx4x4(&vertices[indexVertex].texCoordDiffuse, &texCoords[1], &mtxTexTransform);
				indexVertex++;

				Vec3Copy(&vertices[indexVertex].position, &desVertices[2]);
				Vec3Copy(&vertices[indexVertex].normal, &worldNormal);
				Vec3Copy(&vertices[indexVertex].binormal, &worldBinormal);
				Vec4Copy(&vertices[indexVertex].color, &pParticle->color);
				Vec2MulMtx4x4(&vertices[indexVertex].texCoordDiffuse, &texCoords[2], &mtxTexTransform);
				indexVertex++;

				Vec3Copy(&vertices[indexVertex].position, &desVertices[3]);
				Vec3Copy(&vertices[indexVertex].normal, &worldNormal);
				Vec3Copy(&vertices[indexVertex].binormal, &worldBinormal);
				Vec4Copy(&vertices[indexVertex].color, &pParticle->color);
				Vec2MulMtx4x4(&vertices[indexVertex].texCoordDiffuse, &texCoords[3], &mtxTexTransform);
				indexVertex++;

				pParticle = pParticle->pNext;
			}

			Renderer()->BindVBO(GL_ARRAY_BUFFER, m_vbo);
			Renderer()->UpdateVBO(GL_ARRAY_BUFFER, 0, 4 * numParticles * sizeof(*vertices), vertices);
		}
		SAFE_FREE(vertices);
	}
	//
	// 更新包围盒
	//
	BOOL CSceneNode::UpdateAABB(BOOL bParentUpdate)
	{
		BOOL bUpdate = bParentUpdate || m_bNeedUpdateAABB ? TRUE : FALSE;

		//
		// 1. 可见性检查
		//
		if (m_bVisible == FALSE) {
			return FALSE;
		}

		//
		// 2. 初始化包围盒
		//
		BOOL bAABBCurrentValid = FALSE;
		BOOL bAABBCascadeValid = FALSE;

		Vec3Set(&m_aabbCurrent.minVertex,  FLT_MAX,  FLT_MAX,  FLT_MAX);
		Vec3Set(&m_aabbCurrent.maxVertex, -FLT_MAX, -FLT_MAX, -FLT_MAX);
		Vec3Set(&m_aabbCascade.minVertex,  FLT_MAX,  FLT_MAX,  FLT_MAX);
		Vec3Set(&m_aabbCascade.maxVertex, -FLT_MAX, -FLT_MAX, -FLT_MAX);

		//
		// 3. 更新当前节点包围盒
		//
		if (bUpdate) {
			if (CEntity *pEntity = m_pEntityHead) {
				do {
					if (pEntity->IsRenderable()) {
						const AABB *pAABB = (pEntity->GetType() == CEntity::LIGHT) ? 
							((CEntityLight*)pEntity)->GetAABB() : ((CEntityRenderable*)pEntity)->GetAABB();

						if (IsAABBValid(pAABB)) {
							bAABBCurrentValid = TRUE;
							if (m_aabbCurrent.minVertex[0] > pAABB->minVertex[0]) m_aabbCurrent.minVertex[0] = pAABB->minVertex[0];
							if (m_aabbCurrent.minVertex[1] > pAABB->minVertex[1]) m_aabbCurrent.minVertex[1] = pAABB->minVertex[1];
							if (m_aabbCurrent.minVertex[2] > pAABB->minVertex[2]) m_aabbCurrent.minVertex[2] = pAABB->minVertex[2];
							if (m_aabbCurrent.maxVertex[0] < pAABB->maxVertex[0]) m_aabbCurrent.maxVertex[0] = pAABB->maxVertex[0];
							if (m_aabbCurrent.maxVertex[1] < pAABB->maxVertex[1]) m_aabbCurrent.maxVertex[1] = pAABB->maxVertex[1];
							if (m_aabbCurrent.maxVertex[2] < pAABB->maxVertex[2]) m_aabbCurrent.maxVertex[2] = pAABB->maxVertex[2];
						}
					}
				} while (pEntity = pEntity->pNext);

				if (bAABBCurrentValid) {
					AABBNormalize(&m_aabbCurrent);
					Vec3Copy(&m_aabbCascade.minVertex, &m_aabbCurrent.minVertex);
					Vec3Copy(&m_aabbCascade.maxVertex, &m_aabbCurrent.maxVertex);
				}
				else {
					AABBZero(&m_aabbCurrent);
				}
			}
		}

		//
		// 4. 更新子节点包围盒
		//
		if (CSceneNode *pNode = m_pNodeHead) {
			do {
				if (pNode->UpdateAABB(bUpdate)) {
					if (IsAABBValid(&pNode->m_aabbCascade)) {
						bAABBCascadeValid = TRUE;
						if (m_aabbCascade.minVertex[0] > pNode->m_aabbCascade.minVertex[0]) m_aabbCascade.minVertex[0] = pNode->m_aabbCascade.minVertex[0];
						if (m_aabbCascade.minVertex[1] > pNode->m_aabbCascade.minVertex[1]) m_aabbCascade.minVertex[1] = pNode->m_aabbCascade.minVertex[1];
						if (m_aabbCascade.minVertex[2] > pNode->m_aabbCascade.minVertex[2]) m_aabbCascade.minVertex[2] = pNode->m_aabbCascade.minVertex[2];
						if (m_aabbCascade.maxVertex[0] < pNode->m_aabbCascade.maxVertex[0]) m_aabbCascade.maxVertex[0] = pNode->m_aabbCascade.maxVertex[0];
						if (m_aabbCascade.maxVertex[1] < pNode->m_aabbCascade.maxVertex[1]) m_aabbCascade.maxVertex[1] = pNode->m_aabbCascade.maxVertex[1];
						if (m_aabbCascade.maxVertex[2] < pNode->m_aabbCascade.maxVertex[2]) m_aabbCascade.maxVertex[2] = pNode->m_aabbCascade.maxVertex[2];
					}
				}
			} while (pNode = pNode->pNext);

			if (bAABBCurrentValid || bAABBCascadeValid) {
				AABBNormalize(&m_aabbCascade);
			}
			else {
				AABBZero(&m_aabbCascade);
			}
		}

		//
		// 5. 恢复更新AABB
		//
		m_bNeedUpdateAABB = FALSE;

		return TRUE;
	}