//
	// 更新变换
	// 说明: 自上而下更新
	//
	VOID CSceneNode::UpdateTransform(BOOL bParentUpdate)
	{
		BOOL bUpdate = bParentUpdate || m_bNeedUpdateTransform ? TRUE : FALSE;

		//
		// 1. 更新当前节点变换矩阵
		//
		if (bUpdate) {
			if (m_bNeedUpdateTransform) {
				m_bNeedUpdateTransform = FALSE;

				MATRIX4 mtxScale;
				MATRIX4 mtxRotate;
				MATRIX4 mtxTranslate;
				MATRIX4 mtxScaleRotate;

				MtxDefScale(&mtxScale, m_localScale[0], m_localScale[1], m_localScale[2]);
				MtxDefTranslate(&mtxTranslate, m_localPosition[0], m_localPosition[1], m_localPosition[2]);
				QuatToMtxRotation(&mtxRotate, &m_localOrientation);

				// 级联顺序: scale * rotate * translate
				MtxMul(&mtxScaleRotate, &mtxScale, &mtxRotate);
				MtxMul(&m_mtxLocal, &mtxScaleRotate, &mtxTranslate);
			}

			if (m_pParentNode) {
				MtxMul(&m_mtxWorld, &m_mtxLocal, &m_pParentNode->m_mtxWorld);
			}
			else {
				MtxCopy(&m_mtxWorld, &m_mtxLocal);
			}

			MtxToScale(&m_worldScale, &m_mtxWorld);
			MtxToQuat(&m_worldOrientation, &m_mtxWorld);
			MtxToTranslate(&m_worldPosition, &m_mtxWorld);

			m_dwUpdateTransformCount++;
			m_dwParentUpdateTransformCount = m_pParentNode ? m_pParentNode->m_dwUpdateTransformCount : 0;
		}

		//
		// 2. 更新子节点变换
		//
		if (CSceneNode *pNode = m_pNodeHead) {
			do {
				pNode->UpdateTransform(bUpdate);
			} while (pNode = pNode->pNext);
		}
	}
	//
	// 立即更新变换
	// 说明: 自下而上更新
	//
	VOID CSceneNode::UpdateTransformImmediately(VOID)
	{
		//
		// 1. 更新父节点变换
		//
		if (m_pParentNode) {
			m_pParentNode->UpdateTransformImmediately();
		}

		//
		// 2. 更新当前节点变换矩阵
		//
		if (m_bNeedUpdateTransform || (m_pParentNode && m_pParentNode->m_dwUpdateTransformCount != m_dwParentUpdateTransformCount)) {
			if (m_bNeedUpdateTransform) {
				m_bNeedUpdateTransform = FALSE;

				MATRIX4 mtxScale;
				MATRIX4 mtxRotate;
				MATRIX4 mtxTranslate;
				MATRIX4 mtxScaleRotate;

				MtxDefScale(&mtxScale, m_localScale[0], m_localScale[1], m_localScale[2]);
				MtxDefTranslate(&mtxTranslate, m_localPosition[0], m_localPosition[1], m_localPosition[2]);
				QuatToMtxRotation(&mtxRotate, &m_localOrientation);

				// 级联顺序: scale * rotate * translate
				MtxMul(&mtxScaleRotate, &mtxScale, &mtxRotate);
				MtxMul(&m_mtxLocal, &mtxScaleRotate, &mtxTranslate);
			}

			if (m_pParentNode) {
				MtxMul(&m_mtxWorld, &m_mtxLocal, &m_pParentNode->m_mtxWorld);
			}
			else {
				MtxCopy(&m_mtxWorld, &m_mtxLocal);
			}

			MtxToScale(&m_worldScale, &m_mtxWorld);
			MtxToQuat(&m_worldOrientation, &m_mtxWorld);
			MtxToTranslate(&m_worldPosition, &m_mtxWorld);

			m_dwUpdateTransformCount++;
			m_dwParentUpdateTransformCount = m_pParentNode ? m_pParentNode->m_dwUpdateTransformCount : 0;
		}
	}
Пример #3
0
/* m = m2 * m */
void MtxInvMult(matrix_t m, matrix_t m2)
{
  matrix_t tmp;
  MtxCopy(tmp,m);
  MtxMult3(m, m2, tmp);
}
	//
	// 更新
	//
	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);
	}