#include "StdAfx.h" #include "AdvanceWater.h" #include "NiMath.h" #include "NiTNodeTraversal.h" #ifndef CODE_INGAME using namespace SceneCore; NiImplementRTTI(CAdvanceWater, NiNode); //----------------------------------------------------------------------- CAdvanceWater::CAdvanceWater(void) { m_kTranslation = NiPoint3(0.0f, 0.0f, 0.0f); m_kRotation = NiMatrix3::IDENTITY; m_fScale = 1.0f; } //----------------------------------------------------------------------- CAdvanceWater::~CAdvanceWater(void) { m_spSceneRoot = NULL; m_spEnvMap = NULL; m_spRefractMap = NULL; } //----------------------------------------------------------------------- // 初始化 void CAdvanceWater::Init(NiAVObjectPtr spSceneRoot, stAdvWaterInitParam& initParam) { // 拷贝参数 m_spSceneRoot = spSceneRoot; memcpy(m_afWaveLength, initParam.afWaveLength, sizeof(m_afWaveLength)); memcpy(m_afAmplitude, initParam.afAmplitude, sizeof(m_afAmplitude)); memcpy(m_afSpeed, initParam.afSpeed, sizeof(m_afSpeed)); memcpy(m_avDirection, initParam.avDirection, sizeof(m_avDirection)); //m_fFresnel = initParam.fFresnel; m_fAlpha = initParam.fAlpha; m_kReflectColor = initParam.kReflectColor; m_kSpecularColor = initParam.kSpecularColor; m_kLightDir = initParam.kLightDir; // m_spRefractMap = initParam.spRefractMap; m_spEnvMap = initParam.spEnvMap; // 初始化 material m_spAdvWaterMtl = NiSingleShaderMaterial::Create("AdvanceWater"); NIASSERT(m_spAdvWaterMtl); // 将 layer fog material 赋给 pkForgShapeSceneRoot 中所有 NiGeometry //if (m_spSceneRoot != NULL) //{ // _RecursiveFindAndSetAdvanceWaterMaterial(); // // m_spSceneRoot->SetTranslate(m_kTranslation); // m_spSceneRoot->SetScale(m_fScale); // m_spSceneRoot->SetRotate(m_kRotation); // m_spSceneRoot->Update(0.0f); // m_spSceneRoot->SetLocalTransform(m_spSceneRoot->GetWorldTransform()); // m_spSceneRoot->Update(0.0f); // // 设置 extra data // //NiFloatsExtraData *pkColor = NiNew NiFloatsExtraData( 3, (float *)&m_kColor.r); // //m_pkSceneRoot->AddExtraData("FogColor", pkColor); // //NiFloatExtraData *pkFogDensity = NiNew NiFloatExtraData( m_fDensity ); // //m_pkSceneRoot->AddExtraData("FogDensity", pkFogDensity); // _RefreshWaveParam(); //} SetSceneRoot(spSceneRoot); } //----------------------------------------------------------------------- void CAdvanceWater::_RefreshWaveParam() { if (NULL == m_spSceneRoot) { return; } // 重新计算 波频率 和 相位常数 for (int i=0; i<4; i++) { m_afW[i] = 2 * NI_PI / m_afWaveLength[i]; m_afPhi[i] = m_afSpeed[i] * m_afW[i]; } //Attrib_Point4 Amplitude Artist 0.0,0.0,0.0,0.0 // Attrib_Point4 Frequency Artist 0.0,0.0,0.0,0.0 // Attrib_Point4 Phi Artist 0.0,0.0,0.0,0.0 // Attrib_Point2 WaveDir[4] Artist 0.0,0.0 // Attrib_Float Fresnel Artist 0.02037 // Attrib_Float Alpha Artist 0.5 // Attrib_Point3 ReflectColor Artist 0.7,0.7,0.8 [(0.0,0.0,0.0) (1.0,1.0,1.0)] // Attrib_Point3 RefractColor Artist 0.7,0.8,0.7 [(0.0,0.0,0.0) (1.0,1.0,1.0)] // Attrib_Point3 LightDir Artist 1.0,1.0,0.0 // Attrib_Texture EnvMap Artist 0 // Attrib_Texture RefractMap Artist 1 // Attrib_Float Time Artist 0.0 // 将参数传递到 shanders for (unsigned int i=0; iGetExtraData("Amplitude")); if (pkAmplitude == NULL) { pkAmplitude = NiNew NiFloatsExtraData(4, m_afAmplitude); m_GeometryList[i]->AddExtraData("Amplitude", pkAmplitude); } else { pkAmplitude->SetArray(4, m_afAmplitude); } NiFloatsExtraData *pkFrequency = (NiFloatsExtraData*)(m_GeometryList[i]->GetExtraData("Frequency")); if (pkFrequency == NULL) { pkFrequency = NiNew NiFloatsExtraData(4, m_afW); m_GeometryList[i]->AddExtraData("Frequency", pkFrequency); } else { pkFrequency->SetArray(4, m_afW); } NiFloatsExtraData *pkPhi = (NiFloatsExtraData*)(m_GeometryList[i]->GetExtraData("Phi")); if (pkPhi == NULL) { pkPhi = NiNew NiFloatsExtraData(4, m_afPhi); m_GeometryList[i]->AddExtraData("Phi", pkPhi); } else { pkPhi->SetArray(4, m_afPhi); } NiFloatsExtraData *pkWaveDir = (NiFloatsExtraData*)(m_GeometryList[i]->GetExtraData("WaveDir")); if (pkWaveDir == NULL) { pkWaveDir = NiNew NiFloatsExtraData(8, (float*)(m_avDirection)); m_GeometryList[i]->AddExtraData("WaveDir", pkWaveDir); } else { pkWaveDir->SetArray(8, (float*)(m_avDirection)); } NiFloatExtraData *pkAlpha = (NiFloatExtraData*)(m_GeometryList[i]->GetExtraData("Alpha")); if (pkAlpha == NULL) { pkAlpha = NiNew NiFloatExtraData(m_fAlpha); m_GeometryList[i]->AddExtraData("Alpha", pkAlpha); } else { pkAlpha->SetValue(m_fAlpha); } NiFloatsExtraData *pkReflectColor = (NiFloatsExtraData*)(m_GeometryList[i]->GetExtraData("ColorReflect")); if (pkReflectColor == NULL) { pkReflectColor = NiNew NiFloatsExtraData(3, (float*)&m_kReflectColor); m_GeometryList[i]->AddExtraData("ColorReflect", pkReflectColor); } else { pkReflectColor->SetArray(3, (float*)&m_kReflectColor); } NiFloatsExtraData *pkSpecularColor = (NiFloatsExtraData*)(m_GeometryList[i]->GetExtraData("ColorSpecular")); if (pkSpecularColor == NULL) { pkSpecularColor = NiNew NiFloatsExtraData(3, (float*)&m_kSpecularColor); m_GeometryList[i]->AddExtraData("ColorSpecular", pkSpecularColor); } else { pkSpecularColor->SetArray(3, (float*)&m_kSpecularColor); } NiFloatsExtraData *pkLightDir = (NiFloatsExtraData*)(m_GeometryList[i]->GetExtraData("LightDir")); if (pkLightDir == NULL) { pkLightDir = NiNew NiFloatsExtraData(3, (float*)&m_kLightDir); m_GeometryList[i]->AddExtraData("LightDir", pkLightDir); } else { pkLightDir->SetArray(3, (float*)&m_kLightDir); } NiFloatExtraData *pkTime = (NiFloatExtraData*)(m_GeometryList[i]->GetExtraData("NDL_UpdateTime")); if (pkTime == NULL) { pkTime = NiNew NiFloatExtraData(0.0f); m_GeometryList[i]->AddExtraData("NDL_UpdateTime", pkTime); } NiTexturingProperty* pTexProp = (NiTexturingProperty*)(m_GeometryList[i]->GetProperty(NiProperty::TEXTURING)); if (pTexProp == NULL) { pTexProp = NiNew NiTexturingProperty(); m_GeometryList[i]->AttachProperty(pTexProp); } NiTexturingProperty::ShaderMap* pEnvMap = pTexProp->GetShaderMap(0); if (pEnvMap == NULL) { pEnvMap = NiNew NiTexturingProperty::ShaderMap(); pTexProp->SetShaderMap(0, pEnvMap); } pEnvMap->SetTexture(m_spEnvMap); m_GeometryList[i]->UpdateEffects(); m_GeometryList[i]->UpdateProperties(); m_GeometryList[i]->Update(0.0f); } m_spSceneRoot->UpdateEffects(); m_spSceneRoot->UpdateProperties(); m_spSceneRoot->Update(0.0f); } //---------------------------------------------------------------------------------------------------- // utility functor class MAIN_ENTRY RecursiveAddAdvWaterMaterial { public: RecursiveAddAdvWaterMaterial(CAdvanceWater* pkAdvWater, NiMaterial* spAdvWaterMtl) : m_pkAdvWater(pkAdvWater), m_spAdvWaterMtl(spAdvWaterMtl) {} bool operator() (NiAVObject* pkAVObject) { // Add any particle systems found to soft particle system if (NiIsKindOf(NiGeometry, pkAVObject)) { NiGeometry* pkGeom = NiDynamicCast(NiGeometry, pkAVObject); pkGeom->GetPropertyList().RemoveAll(); pkGeom->RemoveAllExtraData(); bool b = pkGeom->ApplyAndSetActiveMaterial(m_spAdvWaterMtl); //bool b = pkGeom->ApplyAndSetActiveMaterial( "AdvanceWater" ); //bool b = pkGeom->ApplyAndSetActiveMaterial( "AdvanceWater" ); pkGeom->SetSelectiveUpdate(true); pkGeom->SetSelectiveUpdateRigid(true); NiTimeSyncController* pkTimeSyncCtrl = NiNew NiTimeSyncController(); pkTimeSyncCtrl->SetTarget(pkGeom); pkTimeSyncCtrl->Update(0.0f); pkTimeSyncCtrl->Start(); { pkGeom->UpdateProperties(); pkGeom->UpdateEffects(); pkGeom->Update(0.0f); NiShader* pShader = pkGeom->GetShader(); pkGeom->SetShader(pkGeom->GetShaderFromMaterial()); //pShader = pkGeom->GetShaderFromMaterial(); //NiStream stream; //stream.InsertObject( pkGeom ); //pkTimeSyncCtrl->RegisterStreamables(stream); //stream.Save("e:/test/advancewater_test.nif"); } b = pkTimeSyncCtrl->IsStreamable(); //NiShaderDeclaration* pShaderDecl = pkGeom->GetShaderDecl(); m_pkAdvWater->AddGeometry(pkGeom); } return true; } protected: CAdvanceWater* m_pkAdvWater; NiMaterial* m_spAdvWaterMtl; }; //----------------------------------------------------------------------- void CAdvanceWater::_RecursiveFindAndSetAdvanceWaterMaterial() { // 在 fog material 初始化完之后才能调用这个函数 NIASSERT(m_spAdvWaterMtl!=NULL); if (m_spSceneRoot != NULL) { RecursiveAddAdvWaterMaterial kFunctor(this, m_spAdvWaterMtl); NiTNodeTraversal::DepthFirst_AllObjects(m_spSceneRoot, kFunctor); m_spSceneRoot->SetSelectiveUpdatePropertyControllers(true); m_spSceneRoot->UpdateEffects(); m_spSceneRoot->UpdateProperties(); m_spSceneRoot->UpdateControllers(0.0f); m_spSceneRoot->Update(0.0f); } } //----------------------------------------------------------------------- // 添加 Geometry 到 多边形列表 void CAdvanceWater::AddGeometry(NiGeometry* pkGeom) { m_GeometryList.push_back(pkGeom); } //----------------------------------------------------------------------- // 设置/获取波长 void CAdvanceWater::SetWaveLength(UINT uiIndex, float fData) { if (uiIndex<0 || uiIndex>3) { return; } m_afWaveLength[uiIndex] = fData; _RefreshWaveParam(); } //----------------------------------------------------------------------- const float* CAdvanceWater::GetWaveLength() { return m_afWaveLength; } //----------------------------------------------------------------------- // 设置/获取振幅 void CAdvanceWater::SetAmplitude(UINT uiIndex, float fData) { if (uiIndex<0 || uiIndex>3) { return; } m_afAmplitude[uiIndex] = fData; _RefreshWaveParam(); } //----------------------------------------------------------------------- const float* CAdvanceWater::GetAmplitude() { return m_afAmplitude; } //----------------------------------------------------------------------- // 设置/获取波传播速度 void CAdvanceWater::SetSpeed(UINT uiIndex, float fData) { if (uiIndex<0 || uiIndex>3) { return; } m_afSpeed[uiIndex] = fData; _RefreshWaveParam(); } //----------------------------------------------------------------------- const float* CAdvanceWater::GetSpeed() { return m_afSpeed; } //----------------------------------------------------------------------- // 设置/获取方向 void CAdvanceWater::SetWaveDirection(UINT uiIndex, NiPoint2 vWaveDirection) { if (uiIndex >=4) { return; } m_avDirection[uiIndex] = vWaveDirection; _RefreshWaveParam(); } //----------------------------------------------------------------------- NiPoint2* CAdvanceWater::GetWaveDirection() { return m_avDirection; } //----------------------------------------------------------------------- // 设置/获取 Fresnel void CAdvanceWater::SetFresnel(float fFresnel) { m_fFresnel = fFresnel; _RefreshWaveParam(); } //----------------------------------------------------------------------- const float CAdvanceWater::GetFresnel() { return m_fFresnel; } //----------------------------------------------------------------------- // 设置/获取 Alpha void CAdvanceWater::SetAlpha(float fAlpha) { m_fAlpha = fAlpha; _RefreshWaveParam(); } //----------------------------------------------------------------------- const float CAdvanceWater::GetAlpha() { return m_fAlpha; } //----------------------------------------------------------------------- // 设置/获取反射色 void CAdvanceWater::SetReflectColor(NiColor kColor) { m_kReflectColor = kColor; _RefreshWaveParam(); } //----------------------------------------------------------------------- const NiColor CAdvanceWater::GetReflectColor() { return m_kReflectColor; } //----------------------------------------------------------------------- // 设置/获取折射色 void CAdvanceWater::SetSpecularColor(NiColor kColor) { m_kSpecularColor = kColor; _RefreshWaveParam(); } //----------------------------------------------------------------------- const NiColor CAdvanceWater::GetSpecularColor() { return m_kSpecularColor; } //----------------------------------------------------------------------- // 设置/获取光方向 void CAdvanceWater::SetLightDir(NiPoint3 kDir) { m_kLightDir = kDir; _RefreshWaveParam(); } //----------------------------------------------------------------------- const NiPoint3 CAdvanceWater::GetLightDir() { return m_kLightDir; } //----------------------------------------------------------------------- // 设置/获取环境纹理 void CAdvanceWater::SetEnvMap(NiTexturePtr spEnvMap) { m_spEnvMap = spEnvMap; _RefreshWaveParam(); } //----------------------------------------------------------------------- const NiTexturePtr CAdvanceWater::GetEnvMap() { return m_spEnvMap; } //----------------------------------------------------------------------- // 设置/获取折射纹理 void CAdvanceWater::SetRefractMap(NiTexturePtr spRefractMap) { m_spRefractMap = spRefractMap; _RefreshWaveParam(); } //----------------------------------------------------------------------- const NiTexturePtr CAdvanceWater::GetRefractMap() { return m_spRefractMap; } //----------------------------------------------------------------------- // 设置世界变换 void CAdvanceWater::SetTranslate(const NiPoint3& kTranslation) { if (m_kTranslation != kTranslation) { m_kTranslation = kTranslation; if (NULL != m_spSceneRoot) { m_spSceneRoot->SetTranslate(m_kTranslation); m_spSceneRoot->Update(0.0f); m_spSceneRoot->SetLocalTransform(m_spSceneRoot->GetWorldTransform()); m_spSceneRoot->Update(0.0f); } } } //----------------------------------------------------------------------- const NiPoint3& CAdvanceWater::GetTranslate() const { return m_kTranslation; } //----------------------------------------------------------------------- void CAdvanceWater::SetRotate(const NiMatrix3& kRotation) { if (m_kRotation != kRotation) { m_kRotation = kRotation; m_spSceneRoot->SetRotate(m_kRotation); m_spSceneRoot->Update(0.0f); m_spSceneRoot->SetLocalTransform(m_spSceneRoot->GetWorldTransform()); m_spSceneRoot->Update(0.0f); } } //----------------------------------------------------------------------- const NiMatrix3& CAdvanceWater::GetRotate() const { return m_kRotation; } //----------------------------------------------------------------------- void CAdvanceWater::SetScale(const float fScale) { if (m_fScale != fScale) { m_fScale = fScale; m_spSceneRoot->SetScale(m_fScale); m_spSceneRoot->Update(0.0f); m_spSceneRoot->SetLocalTransform(m_spSceneRoot->GetWorldTransform()); m_spSceneRoot->Update(0.0f); } } //----------------------------------------------------------------------- float CAdvanceWater::GetScale() const { return m_fScale; } //----------------------------------------------------------------------- // 设置水表面几何体 void CAdvanceWater::SetSceneRoot(NiAVObjectPtr spSceneRoot) { m_spSceneRoot = spSceneRoot; NiNode::RemoveAllChildren(); m_GeometryList.clear(); // 将 layer fog material 赋给 pkForgShapeSceneRoot 中所有 NiGeometry if (m_spSceneRoot != NULL) { NiNode::AttachChild(spSceneRoot); _RecursiveFindAndSetAdvanceWaterMaterial(); // 设置 alpha property NiAlphaProperty* pkAlphaProp = (NiAlphaProperty*)(m_spSceneRoot->GetProperty(NiProperty::ALPHA)); if (pkAlphaProp == NULL) { pkAlphaProp = NiNew NiAlphaProperty(); m_spSceneRoot->AttachProperty(pkAlphaProp); } pkAlphaProp->SetAlphaBlending(true); pkAlphaProp->SetAlphaTesting(false); pkAlphaProp->SetSrcBlendMode(NiAlphaProperty::ALPHA_SRCALPHA); pkAlphaProp->SetDestBlendMode(NiAlphaProperty::ALPHA_INVSRCALPHA); pkAlphaProp->SetNoSorter(false); m_spSceneRoot->SetSelectiveUpdate(true); m_spSceneRoot->SetTranslate(m_kTranslation); m_spSceneRoot->SetScale(m_fScale); m_spSceneRoot->SetRotate(m_kRotation); m_spSceneRoot->Update(0.0f); m_spSceneRoot->SetLocalTransform(m_spSceneRoot->GetWorldTransform()); m_spSceneRoot->Update(0.0f); } _RefreshWaveParam(); } //----------------------------------------------------------------------- NiAVObjectPtr CAdvanceWater::GetSceneRoot() { return m_spSceneRoot; } //----------------------------------------------------------------------- // 更新 void CAdvanceWater::Update(float fTime, bool bUpdateControllers) { for (unsigned int i=0; iGetExtraData("NDL_UpdateTime")); //pkTime->SetValue(fTime); //m_GeometryList[i]->UpdateProperties(); //m_GeometryList[i]->UpdateEffects(); //m_GeometryList[i]->Update(fTime); } m_spSceneRoot->UpdateProperties(); m_spSceneRoot->UpdateEffects(); m_spSceneRoot->Update(fTime); //NiAVObject::Update(fTime, bUpdateControllers); } //----------------------------------------------------------------------- void CAdvanceWater::BuildVisibleSet(NiEntityRenderingContext* pkRenderingContext) { if (m_spSceneRoot != NULL) { NiCullScene(pkRenderingContext->m_pkCamera, m_spSceneRoot, *(pkRenderingContext->m_pkCullingProcess), *(pkRenderingContext->m_pkCullingProcess->GetVisibleSet()), false); } } //----------------------------------------------------------------------- void CAdvanceWater::RenderImmediate(NiRenderer* pkRenderer) { for (unsigned int i=0; iRenderImmediate(pkRenderer); } } #endif