游戏消耗的CPU资源中,用来做碰撞检测的占大头...
以前的方法是,把每个单位的模型的每个Mesh的BoundingSphere直接进行碰撞检测
缺点很明显,模型的Mesh多了检测次数就会成几何级增长(两个模型每个模型有1个Mesh只需检测一次,而两个模型每个模型有5个Mesh要检测25次,5个模型每个模型有5个Mesh要检测(4+3+2+1)*25 = 250次....)
于是大地无敌就把检测的方法改成:先算出覆盖整个单位的BoundingSphere,如果两个单位的BoundingSphere存在碰撞就检测这两个单位所有Mesh的BoundingSphere,这样可以减少同屏单位数多时的运算量
取单位和射线做碰撞检测的例子,(其中单位所使用的实际Model为DModel.model):

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using AODGameLibrary.Gamehelpers;
using AODGameLibrary.Cameras;
using AODGameLibrary.Units;
using AODGameLibrary.Weapons;
using AODGameLibrary.Models;
using AODGameLibrary.GamePlay;

namespace AODGameLibrary.Gamehelpers
{
    /// 

    /// 处理单位的碰撞检测,最近一次是由大地无敌在2009年8月29日进行改良和优化
    /// 

    public class Collision
    {
    ...
             /// 

        /// 处理单位和射线的碰撞检测
        /// 

        ///          ///          /// 
        public static bool  isCollided(Unit unit, Ray ray)
        {

            BoundingSphere unitBS =new BoundingSphere();
            List bses = new List(0);
            foreach (DModel dModel in unit.model.models)
            {
                if (dModel != null)
                {

                    Matrix[] transforms = new Matrix[dModel.model.Bones.Count];
                    dModel.model.CopyAbsoluteBoneTransformsTo(transforms);
                    foreach (ModelMesh mesh in dModel.model.Meshes)
                    {

                        BoundingSphere bS = mesh.BoundingSphere.Transform(transforms[mesh.ParentBone.Index]
                        * dModel.World);

                        bses.Add(bS);
                        if (unitBS != null)
                        {
                            unitBS = BoundingSphere.CreateMerged(unitBS, bS);
                        }
                        else unitBS = bS;
                    }

                }
            }
            if (unitBS.Intersects(ray) != null)
            {
                foreach (BoundingSphere k in bses)
                {
                    if (k != null)
                    {

                        if (k.Intersects(ray) != null)
                        {
                            return true;
                        }
                    }
                }
            }
            return false;
            

        }
    
     ...
     }
}