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

📄 wmlcollisionrecord.cpp

📁 3D Game Engine Design Source Code非常棒
💻 CPP
字号:
// Magic Software, Inc.
// http://www.magic-software.com
// http://www.wild-magic.com
// Copyright (c) 2003.  All Rights Reserved
//
// The Wild Magic Library (WML) source code is supplied under the terms of
// the license agreement http://www.magic-software.com/License/WildMagic.pdf
// and may not be copied or disclosed except in accordance with the terms of
// that agreement.

#include "WmlBoundingVolumeTree.h"
#include "WmlCollisionRecord.h"
#include "WmlIntrTri3Tri3.h"
#include "WmlTriMesh.h"
using namespace Wml;

//----------------------------------------------------------------------------
CollisionRecord::CollisionRecord (TriMesh* pkMesh, Vector3f* pkVelocity,
    void* pvCallbackData, Callback oCallback, BoundingVolume::Type eType,
    int iMaxTrisPerLeaf, bool bStoreInteriorTris)
{
    assert( pkMesh );

    m_pkMesh = pkMesh;
    m_pkVelocity = pkVelocity;
    m_pvCallbackData = pvCallbackData;
    m_oCallback = oCallback;

    m_pkTree = new BoundingVolumeTree(eType,pkMesh->GetVertexQuantity(),
        pkMesh->Vertices(),pkMesh->GetTriangleQuantity(),
        pkMesh->Connectivity(),iMaxTrisPerLeaf,bStoreInteriorTris);
}
//----------------------------------------------------------------------------
CollisionRecord::~CollisionRecord ()
{
    delete m_pkTree;
}
//----------------------------------------------------------------------------
void CollisionRecord::Initialize ()
{
    m_pkTree->InvalidateWorldBounds();
}
//----------------------------------------------------------------------------
void CollisionRecord::TestIntersection (CollisionRecord& rkRecord)
{
    // for convenience/clarity/readability
    BoundingVolumeTree* pkTree0 = m_pkTree;
    BoundingVolumeTree* pkTree1 = rkRecord.m_pkTree;
    TriMesh* pkMesh0 = m_pkMesh;
    TriMesh* pkMesh1 = rkRecord.m_pkMesh;

    BoundingVolume* pkWorldBV0 = pkTree0->GetWorldBound();
    if ( !pkWorldBV0->IsValid() )
    {
        pkTree0->GetModelBound()->TransformTo(pkWorldBV0,
            pkMesh0->WorldRotate(),
            pkMesh0->WorldTranslate(),
            pkMesh0->WorldScale());
    }

    BoundingVolume* pkWorldBV1 = pkTree1->GetWorldBound();
    if ( !pkWorldBV1->IsValid() )
    {
        pkTree1->GetModelBound()->TransformTo(pkWorldBV1,
            pkMesh1->WorldRotate(),
            pkMesh1->WorldTranslate(),
            pkMesh1->WorldScale());
    }

    if ( pkWorldBV0->TestIntersection(pkWorldBV1) )
    {
        BoundingVolumeTree* pkRoot;

        if ( pkTree0->IsInteriorNode() )
        {
            pkRoot = m_pkTree;

            // compare Tree0.L to Tree1
            m_pkTree = pkRoot->GetLChild();
            TestIntersection(rkRecord);

            // compare Tree0.R to Tree1
            m_pkTree = pkRoot->GetRChild();
            TestIntersection(rkRecord);

            m_pkTree = pkRoot;
        }
        else if ( pkTree1->IsInteriorNode() )
        {
            pkRoot = rkRecord.m_pkTree;

            // compare Tree0 to Tree1.L
            rkRecord.m_pkTree = pkRoot->GetLChild();
            TestIntersection(rkRecord);

            // compare Tree0 to Tree1.R
            rkRecord.m_pkTree = pkRoot->GetRChild();
            TestIntersection(rkRecord);

            rkRecord.m_pkTree = pkRoot;
        }
        else
        {
            int i;

            // at a leaf in each tree
            int iMax0 = pkTree0->GetTriangleQuantity();
            for (int i0 = 0; i0 < iMax0; i0++)
            {
                int iT0 = pkTree0->GetTriangle(i0);

                // get model space triangle
                Vector3f akV0[3];
                pkMesh0->GetTriangle(iT0,akV0[0],akV0[1],akV0[2]);

                // compute world space triangle
                for (i = 0; i < 3; i++)
                {
                    akV0[i] = pkMesh0->WorldScale()*(
                        pkMesh0->WorldRotate()*akV0[i]) +
                        pkMesh0->WorldTranslate();
                }

                int iMax1 = pkTree1->GetTriangleQuantity();
                for (int i1 = 0; i1 < iMax1; i1++)
                {
                    int iT1 = pkTree1->GetTriangle(i1);

                    // get model space triangle
                    Vector3f akV1[3];
                    pkMesh1->GetTriangle(iT1,akV1[0],akV1[1],akV1[2]);

                    // compute world space triangle
                    for (i = 0; i < 3; i++)
                    {
                        akV1[i] = pkMesh1->WorldScale()*(
                            pkMesh1->WorldRotate()*akV1[i]) +
                            pkMesh1->WorldTranslate();
                    }

                    Triangle3f kTri0, kTri1;
                    kTri0.Origin() = akV0[0];
                    kTri0.Edge0() = akV0[1] - akV0[0];
                    kTri0.Edge1() = akV0[2] - akV0[0];
                    kTri1.Origin() = akV1[0];
                    kTri1.Edge0() = akV1[1] - akV0[0];
                    kTri1.Edge1() = akV1[2] - akV0[0];
                    if ( Wml::TestIntersection(kTri0,kTri1) )
                    {
                        if ( m_oCallback )
                            m_oCallback(*this,iT0,rkRecord,iT1,NULL);

                        if ( rkRecord.m_oCallback )
                            rkRecord.m_oCallback(rkRecord,iT1,*this,iT0,NULL);
                    }
                }
            }
        }
    }
}
//----------------------------------------------------------------------------
void CollisionRecord::FindIntersection (CollisionRecord&)
{
    // TO DO.  implement
}
//----------------------------------------------------------------------------
void CollisionRecord::TestIntersection (float, CollisionRecord&)
{
    // TO DO.  implement
}
//----------------------------------------------------------------------------
void CollisionRecord::FindIntersection (float, CollisionRecord&)
{
    // TO DO.  implement
}
//----------------------------------------------------------------------------


⌨️ 快捷键说明

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