#include "CModelNode.h" #include #include #include #include CModelNode::CModelNode(CSceneManager *pScene, CSceneNode *pParent, CModel *pModel) : CSceneNode(pScene, pParent) { SetModel(pModel); mScale = CVector3f(1.f); mLightingEnabled = true; mForceAlphaOn = false; } ENodeType CModelNode::NodeType() { return eModelNode; } void CModelNode::AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo) { if (!mpModel) return; if (!ViewInfo.ViewFrustum.BoxInFrustum(AABox())) return; if (ViewInfo.GameMode) return; if (!mpModel->HasTransparency(mActiveMatSet)) pRenderer->AddOpaqueMesh(this, 0, AABox(), eDrawMesh); else { u32 SurfaceCount = mpModel->GetSurfaceCount(); for (u32 iSurf = 0; iSurf < SurfaceCount; iSurf++) { if (ViewInfo.ViewFrustum.BoxInFrustum(mpModel->GetSurfaceAABox(iSurf).Transformed(Transform()))) { if (!mpModel->IsSurfaceTransparent(iSurf, mActiveMatSet)) pRenderer->AddOpaqueMesh(this, iSurf, mpModel->GetSurfaceAABox(iSurf).Transformed(Transform()), eDrawAsset); else pRenderer->AddTransparentMesh(this, iSurf, mpModel->GetSurfaceAABox(iSurf).Transformed(Transform()), eDrawAsset); } } } if (mSelected) pRenderer->AddOpaqueMesh(this, 0, AABox(), eDrawSelection); } void CModelNode::Draw(ERenderOptions Options, const SViewInfo& ViewInfo) { if (!mpModel) return; if (mForceAlphaOn) Options = (ERenderOptions) (Options & ~eNoAlpha); if (mLightingEnabled) { CGraphics::SetDefaultLighting(); CGraphics::UpdateLightBlock(); CGraphics::sVertexBlock.COLOR0_Amb = CGraphics::skDefaultAmbientColor.ToVector4f(); } else { CGraphics::sNumLights = 0; CGraphics::sVertexBlock.COLOR0_Amb = CColor::skBlack.ToVector4f(); } CGraphics::sPixelBlock.TevColor = CVector4f(1,1,1,1); CGraphics::sPixelBlock.TintColor = TintColor(ViewInfo).ToVector4f(); LoadModelMatrix(); mpModel->Draw(Options, mActiveMatSet); } void CModelNode::DrawAsset(ERenderOptions Options, u32 Asset, const SViewInfo& ViewInfo) { if (!mpModel) return; if (mForceAlphaOn) Options = (ERenderOptions) (Options & ~eNoAlpha); if (mLightingEnabled) { CGraphics::SetDefaultLighting(); CGraphics::UpdateLightBlock(); CGraphics::sVertexBlock.COLOR0_Amb = CGraphics::skDefaultAmbientColor.ToVector4f(); } else { CGraphics::sNumLights = 0; CGraphics::sVertexBlock.COLOR0_Amb = CColor::skBlack.ToVector4f(); } CGraphics::sPixelBlock.TevColor = CVector4f(1,1,1,1); CGraphics::sPixelBlock.TintColor = TintColor(ViewInfo).ToVector4f(); CGraphics::UpdatePixelBlock(); LoadModelMatrix(); mpModel->DrawSurface(Options, Asset, mActiveMatSet); } void CModelNode::DrawSelection() { if (!mpModel) return; LoadModelMatrix(); mpModel->DrawWireframe(eNoRenderOptions, WireframeColor()); } void CModelNode::RayAABoxIntersectTest(CRayCollisionTester &Tester) { if (!mpModel) return; const CRay& Ray = Tester.Ray(); std::pair BoxResult = AABox().IntersectsRay(Ray); if (BoxResult.first) { for (u32 iSurf = 0; iSurf < mpModel->GetSurfaceCount(); iSurf++) { std::pair SurfResult = mpModel->GetSurfaceAABox(iSurf).IntersectsRay(Ray); if (SurfResult.first) Tester.AddNode(this, iSurf, SurfResult.second); } } } SRayIntersection CModelNode::RayNodeIntersectTest(const CRay &Ray, u32 AssetID, const SViewInfo& ViewInfo) { SRayIntersection out; out.pNode = this; out.AssetIndex = AssetID; CRay TransformedRay = Ray.Transformed(Transform().Inverse()); ERenderOptions options = ViewInfo.pRenderer->RenderOptions(); std::pair Result = mpModel->GetSurface(AssetID)->IntersectsRay(TransformedRay, ((options & eEnableBackfaceCull) == 0)); if (Result.first) { out.Hit = true; CVector3f HitPoint = TransformedRay.PointOnRay(Result.second); CVector3f WorldHitPoint = Transform() * HitPoint; out.Distance = Math::Distance(Ray.Origin(), WorldHitPoint); } else out.Hit = false; return out; } void CModelNode::SetModel(CModel *pModel) { mpModel = pModel; mModelToken = CToken(pModel); mActiveMatSet = 0; if (pModel) { SetName(pModel->Source()); mLocalAABox = mpModel->AABox(); } } void CModelNode::ForceAlphaEnabled(bool Enable) { mForceAlphaOn = Enable; }