#include "StdAfx.h" #include "DecalModelBuild.h" #include "Effect/DecalManager.h" #include "Effect/ClipGeometryProcess.h" #include "Effect/DecalEffect.h" DecalModelRenderer::DecalModelRenderer() { } DecalModelRenderer::~DecalModelRenderer() { } void DecalModelRenderer::AddDecal(CEffectBase* pkDecal) { m_DecalMap.SetAt(pkDecal, pkDecal); } bool DecalModelRenderer::RemoveDecal(CEffectBase* pkDecal) { return m_DecalMap.RemoveAt(pkDecal); } void DecalModelRenderer::Clear() { m_DecalMap.RemoveAll(); } bool DecalModelRenderer::BuildDecalPolygon(NiAVObject* pkModel, CEffectBase* pkDecal, int iModelZoneX, int iModelZoneY) { DecalEffect* pkDecalEffect = (DecalEffect*)pkDecal; if (!pkDecalEffect || !pkModel) return false; if (!NiIsKindOf(NiGeometry, pkModel)) return false; if (!pkDecalEffect->IsNeedUpdateMesh() || !pkDecalEffect->IsVisible()) return false; NiPoint3 kDecalWorldPos = pkDecalEffect->GetPosition(); float fRadius = pkDecalEffect->GetRadius(); float fDepth = pkDecalEffect->GetDepth(); NiBound kDecalBound; kDecalBound.SetCenterAndRadius(kDecalWorldPos, NiMax(fRadius, fDepth)); const NiBound& kModelBound = pkModel->GetWorldBound(); if (!NiBound::TestIntersect(0.0f, kDecalBound, NiPoint3::ZERO, kModelBound, NiPoint3::ZERO)) return false; NiGeometry* pkGeometry = (NiGeometry*)pkModel; if (!pkGeometry) return false; const NiTransform& kWorldTransform = pkModel->GetWorldTransform(); NiTriBasedGeom* pkTriBasedGeom = NiDynamicCast(NiTriBasedGeom, pkGeometry); if (!pkTriBasedGeom) return false; //NiAlphaProperty* pkAlpha = (NiAlphaProperty*)pkTriBasedGeom->GetProperty(NiProperty::ALPHA); //if (pkAlpha && (pkAlpha->GetAlphaBlending() || pkAlpha->GetAlphaTesting())) // return false; if (!CClipGeometryProcess::Clip(pkGeometry, kDecalWorldPos, NiPoint3::UNIT_Z, NiPoint3::UNIT_Y, fRadius * 2.0f, fRadius * 2.0f, fDepth)) return false; unsigned short* ausTriList = NiAlloc(unsigned short, CClipGeometryProcess::m_iDecalTriangleCount * 3); unsigned short usIndex = 0; for (unsigned short us = 0; us < CClipGeometryProcess::m_iDecalTriangleCount; us++) { ausTriList[usIndex] = CClipGeometryProcess::m_kTriangleArray[us].index[0]; ausTriList[usIndex + 1] = CClipGeometryProcess::m_kTriangleArray[us].index[1]; ausTriList[usIndex + 2] = CClipGeometryProcess::m_kTriangleArray[us].index[2]; usIndex += 3; } pkDecalEffect->AddPolygon(CClipGeometryProcess::m_iDecalVertexCount, CClipGeometryProcess::m_iDecalTriangleCount, ausTriList, CClipGeometryProcess::m_kVertexArray); NiFree(ausTriList); return true; } void DecalModelRenderer::Render(int iZoneX, int iZoneY, NiAVObject* pkModel) { NiTMapIterator pos = m_DecalMap.GetFirstPos(); while (pos) { CEffectBase* pkDecal = NULL; m_DecalMap.GetNext(pos, pkDecal, pkDecal); if (!pkDecal) continue; if (!BuildDecalPolygon(pkModel, pkDecal, iZoneX, iZoneY)) continue; } }