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; }