#include "StdAfx.h" #include "SceneEffect.h" #include "GameObject.h" #include "Scenemanager.h" #include "ObjectManager.h" #include "ResourceManager.h" #include "ChainEffect.h" #include "Console.h" #define C_EFFECT_VNUM 4 #define C_EFFECT_TNUM 2 CChainEffect::CChainEffect(): m_spBindObjSender(0) ,m_spTexture(0) ,m_spBindObjReceive(0) ,m_fWidth(0.3f) ,m_fActiveTime(0.0f) ,m_fUpdateSpeed(1.0f) ,m_fDelayTime(0.0f) { NiPoint3* pkVerts = NiNew NiPoint3[C_EFFECT_VNUM]; NiPoint3* pkNormals = NiNew NiPoint3[C_EFFECT_VNUM]; NiPoint2* pkTexCoords = NiNew NiPoint2[C_EFFECT_VNUM]; NiColorA* pkColors = NiNew NiColorA[C_EFFECT_VNUM]; unsigned short* pkConnect = NiAlloc(unsigned short, C_EFFECT_TNUM * 3); pkConnect[0] = 0; pkConnect[1] = 1; pkConnect[2] = 2; pkConnect[3] = 2; pkConnect[4] = 1; pkConnect[5] = 3; //Normal pkNormals[0].x = 1.0f; pkNormals[1].x = 1.0f; pkNormals[2].x = 1.0f; pkNormals[3].x = 1.0f; //TextCood pkTexCoords[0].x = 0.0f; pkTexCoords[0].y = 0.0f; pkTexCoords[1].x = 1.0f; pkTexCoords[1].y = 0.0f; pkTexCoords[2].x = 0.0f; pkTexCoords[2].y = 1.0f; pkTexCoords[3].x = 1.0f; pkTexCoords[3].y = 1.0f; NiColorA kDefaultColor = NiColorA(1.0f, 1.0f, 1.0f, 1.0f); //Color pkColors[0] = kDefaultColor; pkColors[1] = kDefaultColor; pkColors[2] = kDefaultColor; pkColors[3] = kDefaultColor; //Seed the system with one quad. NiTriShapeDynamicData* pkData = NiNew NiTriShapeDynamicData(C_EFFECT_VNUM, pkVerts, NULL, pkColors, pkTexCoords, 1, NiGeometryData::NBT_METHOD_NONE, C_EFFECT_TNUM, pkConnect, 0, 0); pkData->SetConsistency(NiGeometryData::VOLATILE); m_pkTriShape = NiNew NiTriShape(pkData); NiStencilProperty* pkStencilProperty = NiNew NiStencilProperty; pkStencilProperty->SetDrawMode(NiStencilProperty::DRAW_BOTH); NiTexturingProperty* pkTexturingProp = NiNew NiTexturingProperty; pkTexturingProp->SetBaseClampMode(NiTexturingProperty::WRAP_S_WRAP_T); pkTexturingProp->SetBaseFilterMode(NiTexturingProperty::FILTER_NEAREST); NiVertexColorProperty* pkColorProperty = NiNew NiVertexColorProperty; pkColorProperty->SetSourceMode(NiVertexColorProperty::SOURCE_IGNORE); pkColorProperty->SetLightingMode(NiVertexColorProperty::LIGHTING_E); NiAlphaProperty* pkAlpha = NiNew NiAlphaProperty; pkAlpha->SetAlphaBlending(true); pkAlpha->SetSrcBlendMode(NiAlphaProperty::ALPHA_SRCALPHA); pkAlpha->SetDestBlendMode(NiAlphaProperty::ALPHA_ONE); NiMaterialProperty* pkMaterial = NiNew NiMaterialProperty; pkMaterial->SetEmittance(NiColor(1.0, 1.0, 1.0)); NiZBufferProperty* pkZ = NiNew NiZBufferProperty; pkZ->SetZBufferTest(true); pkZ->SetZBufferWrite(false); m_pkTriShape->AttachProperty(pkTexturingProp); m_pkTriShape->AttachProperty(pkStencilProperty); m_pkTriShape->AttachProperty(pkZ); m_pkTriShape->AttachProperty(pkMaterial); m_pkTriShape->AttachProperty(pkAlpha); m_spEffectNode = NiNew NiNode; m_spEffectNode->AttachChild(m_pkTriShape); m_spEffectNode->UpdateProperties(); m_spEffectNode->UpdateEffects(); m_spEffectNode->UpdateNodeBound(); m_spEffectNode->Update(0); } CChainEffect::~CChainEffect(void) { } void CChainEffect::BindObject(NiAVObject* pkSrcObj, NiAVObject* pkDestObj) { m_spBindObjSender = pkSrcObj; m_spBindObjReceive = pkDestObj; } void CChainEffect::SetTexture(const char* szTexFile ) { if (!m_pkTriShape) return; m_spTexture = 0; m_spTexture = NiSourceTexture::Create(szTexFile); NiTexturingProperty* pkTexturingProp = (NiTexturingProperty*)m_pkTriShape->GetProperty(NiProperty::TEXTURING); if (!pkTexturingProp) pkTexturingProp = NiNew NiTexturingProperty; if (!pkTexturingProp) { NIASSERT(0); return; } pkTexturingProp->SetBaseTexture(m_spTexture); } void CChainEffect::SetColor(NiColor& kColor) { NiMaterialProperty* pkMat = (NiMaterialProperty*)m_pkTriShape->GetProperty(NiProperty::MATERIAL); if ( pkMat ) pkMat->SetEmittance( kColor ); } void CChainEffect::UpdateEffect(float fTimeLine, float fDeltaTime) { if ( m_fDelayTime > 0.0f ) { m_fDelayTime -= fDeltaTime; return; } if ( IsAutoDelete() && m_fActiveTime < 9999.0f) { m_fActiveTime -= fDeltaTime; if ( m_fActiveTime <= 0.0f ) { Deactivate(); return; } } //Texture UV NiPoint2* pkUV = m_pkTriShape->GetTextures(); pkUV[0].x += fDeltaTime * m_fUpdateSpeed; pkUV[2].x += fDeltaTime * m_fUpdateSpeed; pkUV[1].x += fDeltaTime * m_fUpdateSpeed; pkUV[3].x += fDeltaTime * m_fUpdateSpeed; Sample(fTimeLine); } void CChainEffect::RenderEffect(const NiCamera* pkCamera) { if (!m_spEffectNode) return; SceneMgr->RenderObject(m_spEffectNode); } NiMatrix3 LookAt(NiPoint3 kEyePos, NiPoint3 kLookAt) { NiPoint3 kWorldUp(0.0, 0.0, 1.0f); NiPoint3 kDir = kEyePos - kLookAt; kDir.Unitize(); NiPoint3 kRight = kWorldUp.UnitCross(kDir); NiPoint3 kUp = kDir.UnitCross(kRight); NiMatrix3 kRot = NiMatrix3(-kDir, kUp, kRight); return kRot; } void CChainEffect::Sample(float fTime) { CPlayerLocal* pkLocalPlayer = ObjectMgr->GetLocalPlayer(); if (!m_spBindObjSender || !m_spBindObjReceive || !pkLocalPlayer) return; float fElapsed = GetElapsed(); const NiPoint3& kSenderPos = m_spBindObjSender->GetWorldTranslate(); const NiPoint3& kReceiverPos = m_spBindObjReceive->GetWorldTranslate(); const NiCamera& kCamera = pkLocalPlayer->GetCamera().GetNiCamera(); NiPoint3* pkVerts = m_pkTriShape->GetVertices(); NiPoint3 kDir = kReceiverPos - kSenderPos; kDir.Unitize(); float fDistance = (kReceiverPos - kSenderPos).Length(); NiPoint3 kFinalPos = kDir * fDistance; NiPoint3 kTemp[4]; kTemp[0].x = 0.0f; kTemp[0].y = 0.0f; kTemp[0].z = m_fWidth; kTemp[2].x = 0.0f; kTemp[2].y = 0.0f; kTemp[2].z = -m_fWidth; kTemp[1].x = kFinalPos.x; kTemp[1].y = kFinalPos.y; kTemp[1].z = kFinalPos.z + m_fWidth; kTemp[3].x = kFinalPos.x; kTemp[3].y = kFinalPos.y; kTemp[3].z = kFinalPos.z-m_fWidth; NiMatrix3 kTestMat; kTestMat.MakeIdentity(); NiPoint3 kCameraPos = kCamera.GetWorldTranslate(); NiPoint3 kCenterToCameraDir = kCameraPos - kSenderPos; kCenterToCameraDir.Unitize(); NiPoint3 kZUpDir = NiPoint3::UNIT_Z; NiPoint3 kTestDir = kDir.Cross( kZUpDir ); float fTestDot = kCenterToCameraDir.Dot( kTestDir ); float fHalfPI = NI_PI * 0.5f; float fDot = kCenterToCameraDir.Dot( kZUpDir ); float fSideData = fDot + 1.0f; float fAngle = NiACos(fDot) - fHalfPI; if ( fTestDot > 0.0f ) fAngle = -fAngle; kTestMat.MakeRotation(fAngle, kDir); kTemp[0] = kTestMat * kTemp[0]; kTemp[2] = kTestMat * kTemp[2]; kTemp[1] = kTestMat * kTemp[1]; kTemp[3] = kTestMat * kTemp[3]; //Src Pos pkVerts[0] = kSenderPos + kTemp[0]; pkVerts[2] = kSenderPos + kTemp[2]; pkVerts[1] = kSenderPos + kTemp[1]; pkVerts[3] = kSenderPos + kTemp[3]; //----------------------------------------------------------------------- //Call MarkAsChanged to inform the renderer to repack. NiTriShapeDynamicData* pkData = (NiTriShapeDynamicData*)(m_pkTriShape-> GetModelData()); pkData->SetActiveTriangleCount(C_EFFECT_TNUM); pkData->SetActiveVertexCount(C_EFFECT_VNUM); pkData->MarkAsChanged(NiGeometryData::VERTEX_MASK | NiGeometryData::TEXTURE_MASK | NiGeometryData::COLOR_MASK); //Update the bound for proper sorting and culling. NiBound kBound; kBound.ComputeFromData(C_EFFECT_VNUM, pkVerts); m_pkTriShape->SetModelBound(kBound); m_pkTriShape->Update(0.0f, false); }