新的碰撞检测类..

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

游戏消耗的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
{
    /// <summary>
    /// 处理单位的碰撞检测,最近一次是由大地无敌在2009年8月29日进行改良和优化
    /// </summary>
    public class Collision
    {
    ...
             /// <summary>
        /// 处理单位和射线的碰撞检测
        /// </summary>
        /// <param name="unit"></param>
        /// <param name="ray"></param>
        /// <returns></returns>
        public static bool  isCollided(Unit unit, Ray ray)
        {

            BoundingSphere unitBS =new BoundingSphere();
            List<BoundingSphere> bses = new List<BoundingSphere>(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;
            

        }
    
     ...
     }
}

1 thought on “新的碰撞检测类..”

  1. 每次访问你的BLOG,就提示要下在密码管理器,是不是设置一下,这样也太流氓了吧

    大地无敌 于 2009-9-6 21:07:32 回复

    不会呀,大地无敌认为这里是很干净的地方绝对没有设置过强制下密码生成器哦,请检查一下浏览器是否正常,以及地址是否为http://www.gquit.cn,或者换个浏览器看看是否还有弹出下载的问题

Leave a Reply

Your email address will not be published. Required fields are marked *