⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mgcbspnode.cpp

📁 3D Game Engine Design Source Code非常棒
💻 CPP
字号:
// Magic Software, Inc.
// http://www.magic-software.com
// Copyright (c) 2000, All Rights Reserved
//
// Source code from Magic Software is supplied under the terms of a license
// agreement and may not be copied or disclosed except in accordance with the
// terms of that agreement.  The various license agreements may be found at
// the Magic Software web site.  This file is subject to the license
//
// RESTRICTED USE SOURCE CODE
// http://www.magic-software.com/License/restricted.pdf

#include "MgcBspNode.h"
#include "MgcRenderer.h"

MgcImplementRTTI(MgcBspNode,MgcNode);
MgcImplementStream(MgcBspNode);

//----------------------------------------------------------------------------
MgcBspNode::MgcBspNode ()
    :
    MgcNode(3,0)
{
    m_oCallback = 0;
    m_pvData = 0;
}
//----------------------------------------------------------------------------
MgcSpatialPtr MgcBspNode::AttachLeftChild (MgcSpatial* pkChild)
{
    return SetChild(0,pkChild);
}
//----------------------------------------------------------------------------
MgcSpatialPtr MgcBspNode::AttachRightChild (MgcSpatial* pkChild)
{
    return SetChild(2,pkChild);
}
//----------------------------------------------------------------------------
MgcSpatialPtr MgcBspNode::DetachLeftChild ()
{
    return DetachChildAt(0);
}
//----------------------------------------------------------------------------
MgcSpatialPtr MgcBspNode::DetachRightChild ()
{
    return DetachChildAt(2);
}
//----------------------------------------------------------------------------
MgcSpatialPtr MgcBspNode::GetLeftChild ()
{
    return GetChild(0);
}
//----------------------------------------------------------------------------
MgcSpatialPtr MgcBspNode::GetRightChild ()
{
    return GetChild(2);
}
//---------------------------------------------------------------------------
void MgcBspNode::UpdateWorldData (MgcReal fAppTime)
{
    MgcNode::UpdateWorldData(fAppTime);

    // Let X represent points in model space and Y = s*R*X+T represent
    // points in world space where s is the world scale, R is the world
    // rotation, and T is the world translation.  The inverse transform is
    // X = (1/s)*R^t*(Y-T).  The model plane is Dot(N0,X) = C0.  Replacing
    // the formula for X in it and applying some algebra leads to the world
    // plane Dot(N1,Y) = C1 where N1 = R*N0 and C1 = s*C0+Dot(N1,T).

    MgcVector3 kNormal = m_kWorldRotate*m_kModelPlane.Normal();
    MgcReal fConstant = m_fWorldScale*m_kModelPlane.Constant() +
        kNormal.Dot(m_kWorldTranslate);

    m_kWorldPlane.Normal() = kNormal;
    m_kWorldPlane.Constant() = fConstant;
}
//---------------------------------------------------------------------------
void MgcBspNode::Draw (MgcRenderer& rkRenderer)
{
    // draw children in back-to-front order
    MgcSpatial* pkLeft = m_aspkChild[0];
    MgcSpatial* pkRight = m_aspkChild[1];

    MgcCameraPtr spkCamera = rkRenderer.GetCamera();
    MgcReal fSgnDist = m_kWorldPlane.DistanceTo(spkCamera->GetLocation());
    MgcReal fNdD = m_kWorldPlane.Normal().Dot(spkCamera->GetDirection());
    MgcReal fCosSqr = spkCamera->GetMaxCosSqrFrustumAngle();

    if ( fSgnDist > 0.0 )
    {
        if ( -fNdD >= fCosSqr )
        {
            if ( pkRight )
                pkRight->Draw(rkRenderer);

            if ( m_oCallback )
                m_oCallback();
        }

        if ( pkLeft )
            pkLeft->Draw(rkRenderer);
    }
    else if ( fSgnDist < 0.0 )
    {
        if ( fNdD >= fCosSqr )
        {
            if ( pkLeft )
                pkLeft->Draw(rkRenderer);

            if ( m_oCallback )
                m_oCallback();
        }

        if ( pkRight )
            pkRight->Draw(rkRenderer);
    }
    else  if ( fNdD >= 0.0 )
    {
        if ( -fNdD >= fCosSqr )
        {
            if ( pkRight )
                pkRight->Draw(rkRenderer);

            if ( m_oCallback )
                m_oCallback();
        }

        if ( pkLeft )
            pkLeft->Draw(rkRenderer);
    }
    else
    {
        if ( fNdD >= fCosSqr )
        {
            if ( pkLeft )
                pkLeft->Draw(rkRenderer);

            if ( m_oCallback )
                m_oCallback();
        }

        if ( pkRight )
            pkRight->Draw(rkRenderer);
    }
}
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// streaming
//---------------------------------------------------------------------------
MgcObject* MgcBspNode::Factory (MgcStream& rkStream)
{
    MgcBspNode* pkObject = new MgcBspNode;
    MgcStream::Link* pkLink = new MgcStream::Link(pkObject);
    pkObject->Load(rkStream,pkLink);
    return pkObject;
}
//---------------------------------------------------------------------------
void MgcBspNode::Load (MgcStream& rkStream, MgcStream::Link* pkLink)
{
    MgcNode::Load(rkStream,pkLink);
}
//---------------------------------------------------------------------------
void MgcBspNode::Link (MgcStream& rkStream, MgcStream::Link* pkLink)
{
    MgcNode::Link(rkStream,pkLink);
}
//---------------------------------------------------------------------------
bool MgcBspNode::Register (MgcStream& rkStream)
{
    return MgcNode::Register(rkStream);
}
//---------------------------------------------------------------------------
void MgcBspNode::Save (MgcStream& rkStream)
{
    MgcNode::Save(rkStream);
}
//---------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -