青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

天行健 君子當(dāng)自強(qiáng)而不息

幾何檢測(cè)(6)

新建網(wǎng)頁(yè) 1

 

前面都提到了cAABB3類,它代表的是3D中的軸對(duì)齊矩形邊界框(AABB),這里給出類的完整定義和實(shí)現(xiàn)。

AABb3.h:

    #ifndef AABB3_H
   
#define AABB3_H
   
    #include "vector3.h"
   
   
class cMatrix4x3;
   
   
//---------------------------------------------------------------------------
    // Implement a 3D axially aligned bounding box
    //---------------------------------------------------------------------------
   
class cAABB3
    {
   
public:
        cVector3 min, max;
   
   
public:
        
// query for dimentions
   
    cVector3 size() const        { return max - min; }
        
float     x_size()            { return max.x - min.x; }
        
float     y_size()            { return max.y - min.y; }
        
float     z_size()            { return max.z - min.z; }
        cVector3 center() 
const        { return (min + max) * 0.5f; }
   
        
// fetch one of the eight corner points
   
    cVector3 corner(int i) const;
   
        
// "Empty" the box, by setting the values to really large/small numbers.
   
    void empty();
   
        
// add a point to the box
   
    void add(const cVector3& p);
   
        
// add an AABB to the box
   
    void add(const cAABB3& box);
   
        
// return true if the box is empty
   
    bool is_empty() const;
   
        
// return true if the box contains a point
   
    bool contains(const cVector3& p) const;
   
        
// transform the box and compute the new AABB
   
    void set_to_transformed_box(const cAABB3& box, const cMatrix4x3& m);
   
        
// return the clostet point on this box to another point
   
    cVector3 closest_point_to(const cVector3& p) const;
   
        
// return true if we intersect a sphere
   
    bool intersect_sphere(const cVector3& center, float radius) const;
   
        
// Parametric intersection with a ray, returns >1 if no intresection.
   
    float ray_intersect(const cVector3& ray_org, const cVector3& ray_delta, cVector3* return_normal) const;
   
        
// classify box as being on one side or the other side of a plane
   
    int classify_plane(const cVector3& n, float d) const;
   
        
// dynamic intersection with plane
   
    float intersect_plane(const cVector3& n, float plane_d, const cVector3& dir) const;
    };
   
   
// Check if two AABBs intersect, and return true if so.
    // Optionally return the AABB of their intersection if an intersection is dectected.
   
bool intersect_aabb(const cAABB3& box1, const cAABB3& box2, cAABB3* box_intersect);
   
   
    // Return parametric point in time when a moving AABB collides with a stationary AABB.
    // return value > 1 if no intersection.
   
float intersect_moving_aabb(const cAABB3& stationary_aabb, const cAABB3& moving_aabb, const cVector3& d);
   
   
#endif

AABB3.cpp:

    #include <assert.h>
    #include <stdlib.h>
    #include "AABB3.h"
    #include "Matrix4x3.h"
    #include "CommonStuff.h"
   
   
const float NO_INTERSECTION = 1e30f;    // We'll return this huge number if no intersection
   
    //--------------------------------------------------------------------------------------
    // Return one of the 8 corner points.  The points are numbered as follows:
    //
    //            6                                7
    //              ------------------------------
    //             /|                           /|
    //            / |                          / |
    //           /  |                         /  |
    //          /   |                        /   |
    //         /    |                       /    |
    //        /     |                      /     |
    //       /      |                     /      |
    //      /       |                    /       |
    //     /        |                   /        |
    //  2 /         |                3 /         |
    //   /----------------------------/          |
    //   |          |                 |          |
    //   |          |                 |          |      +Y
    //   |        4 |                 |          | 
    //   |          |-----------------|----------|      |
    //   |         /                  |         /  5    |
    //   |        /                   |        /        |       +Z
    //   |       /                    |       /         |
    //   |      /                     |      /          |     /
    //   |     /                      |     /           |    /
    //   |    /                       |    /            |   /
    //   |   /                        |   /             |  /
    //   |  /                         |  /              | /
    //   | /                          | /               |/
    //   |/                           |/                ----------------- +X
    //   ------------------------------
    //  0                              1
    //
    // Bit 0 selects min.x vs. max.x
    // Bit 1 selects min.y vs. max.y
    // Bit 2 selects min.z vs. max.z
    //--------------------------------------------------------------------------------------
   
cVector3 cAABB3::corner(int i) const
    {
        assert(i >= 0 && i <= 7);    
// make sure index is in range
   

        
return cVector3((i & 1) ? max.x : min.x,
                        (i & 2) ? max.y : min.y,
                        (i & 4) ? max.z : min.z);
    }
   
   
//---------------------------------------------------------------------------
    // "Empty" the box, by setting the values to really large/small numbers.
    //---------------------------------------------------------------------------
   
void cAABB3::empty() 
    {
        
const float big_number = 1e37f;
   
        min.x = min.y = min.z = big_number;
        max.x = max.y = max.z = -big_number;
    }
   
   
//---------------------------------------------------------------------------
    // Add a point to the box
    //---------------------------------------------------------------------------
   
void cAABB3::add(const cVector3& p)
    {
        
// expand the box as necessary to contain the point
   
    if(p.x < min.x)        min.x = p.x;
        
if(p.x > max.x)        max.x = p.x;
        
if(p.y < min.y)        min.y = p.y;
        
if(p.y > max.y)        max.y = p.y;
        
if(p.z < min.z)        min.z = p.z;
        
if(p.z > max.z)        max.z = p.z;
    }
   
   
//---------------------------------------------------------------------------
    // Add an AABB to the box
    //---------------------------------------------------------------------------
   
void cAABB3::add(const cAABB3& box)
    {
        
// expand the box as necessary
   
    if(box.min.x < min.x)    min.x = box.min.x;
        
if(box.min.x > max.x)    max.x = box.min.x;
        
if(box.min.y < min.y)    min.y = box.min.y;
        
if(box.min.y > max.y)    max.y = box.min.y;
        
if(box.min.z < min.z)    min.z = box.min.z;
        
if(box.min.z > max.z)    max.z = box.min.z;
    }
   
   
//---------------------------------------------------------------------------
    // Return true if the box is empty
    //---------------------------------------------------------------------------
   
bool cAABB3::is_empty() const
    {
        
// check if we're inverted on any axis
   
    return (min.x > max.x) || (min.y > max.y) || (min.z > max.z);
    }
   
   
//---------------------------------------------------------------------------
    // Return true if the box contains a point
    //---------------------------------------------------------------------------
   
bool cAABB3::contains(const cVector3& p) const
    {
        
// check for overlap on each axis
   
    return (p.x >= min.x) && (p.x <= max.x) &&
               (p.y >= min.y) && (p.y <= max.y) &&
               (p.z >= min.z) && (p.z <= max.z);
    }
   
   
//---------------------------------------------------------------------------
    // Transform the box and compute the new AABB.  Remember, this always
    // results in an AABB that is at least as big as the origin, and may be
    // considerably bigger.
    //---------------------------------------------------------------------------
   
void cAABB3::set_to_transformed_box(const cAABB3& box, const cMatrix4x3& m)
    {
        
// if we're empty, then bail.
   
    if(box.is_empty())
        {
            empty();
            
return;
        }
   
        
// start with the translation portion
   
    min = max = get_translation(m);
   
        
// examine each of the 9 matrix elements and compute the new AABB
   

        
if(m.m11 > 0.0f)
        {
            min.x += m.m11 * box.min.x;
            max.x += m.m11 * box.max.x;
        }
        
else
        {
            min.x += m.m11 * box.max.x;
            max.x += m.m11 * box.min.x;
        }
   
        
if(m.m21 > 0.0f)
        {
            min.x += m.m21 * box.min.y; 
            max.x += m.m21 * box.max.y;
        }
        
else
        {
            min.x += m.m21 * box.max.y; 
            max.x += m.m21 * box.min.y;
        }
   
        
if(m.m31 > 0.0f)
        {
            min.x += m.m31 * box.min.z; 
            max.x += m.m31 * box.max.z;
        }
        
else
        {
            min.x += m.m31 * box.max.z; 
            max.x += m.m31 * box.min.z;
        }
   
        
if(m.m12 > 0.0f) 
        {
            min.y += m.m12 * box.min.x; 
            max.y += m.m12 * box.max.x;
        }
        
else
        {
            min.y += m.m12 * box.max.x; 
            max.y += m.m12 * box.min.x;
        }
   
        
if(m.m22 > 0.0f)
        {
            min.y += m.m22 * box.min.y; 
            max.y += m.m22 * box.max.y;
        }
        
else
        {
            min.y += m.m22 * box.max.y; 
            max.y += m.m22 * box.min.y;
        }
   
        
if(m.m32 > 0.0f)
        {
            min.y += m.m32 * box.min.z; 
            max.y += m.m32 * box.max.z;
        }
        
else
        {
            min.y += m.m32 * box.max.z; 
            max.y += m.m32 * box.min.z;
        }
   
        
if(m.m13 > 0.0f) 
        {
            min.z += m.m13 * box.min.x; 
            max.z += m.m13 * box.max.x;
        }
        
else
        {
            min.z += m.m13 * box.max.x; 
            max.z += m.m13 * box.min.x;
        }
   
        
if(m.m23 > 0.0f)
        {
            min.z += m.m23 * box.min.y; 
            max.z += m.m23 * box.max.y;
        }
        
else
        {
            min.z += m.m23 * box.max.y; 
            max.z += m.m23 * box.min.y;
        }
   
        
if(m.m33 > 0.0f)
        {
            min.z += m.m33 * box.min.z; 
            max.z += m.m33 * box.max.z;
        }
        
else
        {
            min.z += m.m33 * box.max.z; 
            max.z += m.m33 * box.min.z;
        }
    }
   
   
//---------------------------------------------------------------------------
    // return the closest point on this box to another point
    //---------------------------------------------------------------------------
   
cVector3 cAABB3::closest_point_to(const cVector3& p) const
    {
        
// "push" p into the box, on each dimension.
   

        cVector3 r;
   
        
if(p.x < min.x)
            r.x = min.x;
        
else if(p.x > max.x)
            r.x = max.x;
        
else
            r.x = p.x;
   
        
if(p.y < min.y) 
            r.y = min.y;
        
else if(p.y > max.y) 
            r.y = max.y;
        
else
            r.y = p.y;
   
        
if(p.z < min.z)
            r.z = min.z;
        
else if(p.z > max.z)
            r.z = max.z;
        
else
            r.z = p.z;
   
        
return r;
    }
   
   
//---------------------------------------------------------------------------
    // Return true if we intersect a sphere, uses Arvo's algorithm.
    //---------------------------------------------------------------------------
   
bool cAABB3::intersect_sphere(const cVector3& center, float radius) const
    {
        
// find the closest point on box to the point
   
    cVector3 closest_point = closest_point_to(center);
   
        
// check if it's within range
   
    return distance_squared(center, closest_point) < radius * radius;
    }
   
   
//---------------------------------------------------------------------------
    // Parametric intersection with a ray.  Returns parametric point
    // of intsersection in range 01 or a really big number (>1) if no
    // intersection.
    //
    // From "Fast Ray-Box Intersection," by Woo in Graphics Gems I, page 395.
    //
    // See 12.9.11
    //---------------------------------------------------------------------------
   
float cAABB3::ray_intersect(const cVector3& ray_org,        // origin of the ray
   
                            const cVector3& ray_delta,        // length and direction of the ray
   
                                cVector3* return_normal) const    // optionally, the normal is returned
   
{    
        
// Check for point inside box, trivial reject, and determine parametric distance to each front face.
   
    bool inside = true;
   
        
float xt, xn = 0.0f;
   
        
if (ray_org.x < min.x) 
        {
            xt = min.x - ray_org.x;
            
if (xt > ray_delta.x) 
                
return NO_INTERSECTION;
   
            xt /= ray_delta.x;
            inside = 
false;
            xn = -1.0f;
        } 
        
else if (ray_org.x > max.x) 
        {
            xt = max.x - ray_org.x;
            
if (xt < ray_delta.x) 
                
return NO_INTERSECTION;
   
            xt /= ray_delta.x;
            inside = 
false;
            xn = 1.0f;
        } 
        
else
            xt = -1.0f;    
   
        
float yt, yn = 0.0f;
   
        
if (ray_org.y < min.y) 
        {
            yt = min.y - ray_org.y;
            
if (yt > ray_delta.y) 
                
return NO_INTERSECTION;
   
            yt /= ray_delta.y;
            inside = 
false;
            yn = -1.0f;
        } 
        
else if (ray_org.y > max.y) 
        {
            yt = max.y - ray_org.y;
            
if (yt < ray_delta.y) 
                
return NO_INTERSECTION;
   
            yt /= ray_delta.y;
            inside = 
false;
            yn = 1.0f;
        } 
        
else 
            yt = -1.0f;    
   
        
float zt, zn = 0.0f;
   
        
if (ray_org.z < min.z) 
        {
            zt = min.z - ray_org.z;
            
if (zt > ray_delta.z) 
                
return NO_INTERSECTION;
   
            zt /= ray_delta.z;
            inside = 
false;
            zn = -1.0f;
        } 
        
else if (ray_org.z > max.z) 
        {
            zt = max.z - ray_org.z;
            
if (zt < ray_delta.z) 
                
return NO_INTERSECTION;
   
            zt /= ray_delta.z;
            inside = 
false;
            zn = 1.0f;
        } 
        
else 
            zt = -1.0f;    
   
        
// Inside box?
   
    if (inside) 
        {
            
if (return_normal != NULL) 
            {
                *return_normal = -ray_delta;
                return_normal->normalize();
            }
   
            
return 0.0f;
        }
   
        
// Select farthest plane - this is the plane of intersection.
   

        
int which = 0;
        
float t = xt;
   
        
if (yt > t) 
        {
            which = 1;
            t = yt;
        }
   
        
if (zt > t) 
        {
            which = 2;
            t = zt;
        }
   
        
switch (which) 
        {
        
case 0: // intersect with yz plane
   
      {
            
float y = ray_org.y + ray_delta.y * t;
   
            
if (y < min.y || y > max.y) 
                
return NO_INTERSECTION;
   
            
float z = ray_org.z + ray_delta.z * t;
            
if (z < min.z || z > max.z) 
                
return NO_INTERSECTION;
   
            
if (return_normal != NULL) 
            {
                return_normal->x = xn;
                return_normal->y = 0.0f;
                return_normal->z = 0.0f;
            }
          } 
          
break;
   
        
case 1: // intersect with xz plane
   
      {
            
float x = ray_org.x + ray_delta.x * t;
            
if (x < min.x || x > max.x) 
                
return NO_INTERSECTION;
   
            
float z = ray_org.z + ray_delta.z * t;
            
if (z < min.z || z > max.z) 
                
return NO_INTERSECTION;
   
            
if (return_normal != NULL) 
            {
                return_normal->x = 0.0f;
                return_normal->y = yn;
                return_normal->z = 0.0f;
            }
   
          } 
          
break;
   
        
case 2: // intersect with xy plane
   
      {
            
float x = ray_org.x + ray_delta.x * t;
            
if (x < min.x || x > max.x) 
                
return NO_INTERSECTION;
   
            
float y = ray_org.y + ray_delta.y * t;
            
if (y < min.y || y > max.y) 
                
return NO_INTERSECTION;
   
            
if (return_normal != NULL) 
            {
                return_normal->x = 0.0f;                                
                return_normal->y = 0.0f;
                return_normal->z = zn;
            }
          } 
          
break;
        }
   
        
// Return parametric point of intersection
   
    return t;
    }
   
   
//---------------------------------------------------------------------------
    // Perform static AABB-plane intersection test.  Returns:
    //
    // <0    Box is completely on the BACK side of the plane
    // >0    Box is completely on the FRONT side of the plane
    // 0    Box intersects the plane
    //---------------------------------------------------------------------------
   
int cAABB3::classify_plane(const cVector3& n, float d) const
    {
        
// inspect the normal and compute the minimum and maximum d value
   
    
        
float min_d, max_d;
   
        
if (n.x > 0.0f) 
        {
            min_d = n.x * min.x; 
            max_d = n.x * max.x;
        } 
        
else 
        {
            min_d = n.x * max.x; 
            max_d = n.x * min.x;
        }
   
        
if (n.y > 0.0f) 
        {
            min_d += n.y * min.y; 
            max_d += n.y * max.y;
        } 
        
else 
        {
            min_d += n.y * max.y; 
            max_d += n.y * min.y;
        }
   
        
if (n.z > 0.0f) 
        {
            min_d += n.z * min.z; 
            max_d += n.z * max.z;
        } 
        
else 
        {
            min_d += n.z * max.z; 
            max_d += n.z * min.z;
        }
   
        
// check if completely on the front side of the plane
   
    if(min_d >= d)
            
return 1;
   
        
// check if completely on the back side of the plane
   
    if(max_d <= d)
            
return -1;
   
        
// we straddle the plane
   
    return 0;
    }
   
   
//---------------------------------------------------------------------------
    // Perform dynamic AABB-plane intersection test.
    //
    // n        is the plane normal (assumed to be normalized)
    // plane_d    is the D value of the plane equation p.n = d
    // dir        dir is the direction of movement of the AABB.
    //
    // The plane is assumed to be stationary.
    //
    // Returns the parametric point of intersection - the distance traveled
    // before an intersection occurs.  If no intersection, a REALLY big
    // number is returned.  You must check against the length of the displacement.
    //
    // Only intersections with the front side of the plane are detected.
    //---------------------------------------------------------------------------
   
float cAABB3::intersect_plane(const cVector3& n, float plane_d, const cVector3& dir) const
    {
        
// make sure they are passing in normalized vectors
   
        assert(fabs(n * n - 1.0) < 0.01);
        assert(fabs(dir * dir - 1.0) < 0.01);
        
        
// compute glancing angle, make sure we are moving towards the front of the plane.
   
    float dot = n * dir;
        
if(dot >= 0.0f)
            
return NO_INTERSECTION;
   
        
// inspect the normal and compute the minimum and maximum d values.
        // min_d is the d value of the "frontmost" corner point.
   

        
float min_d, max_d;
   
        
if (n.x > 0.0f) 
        {
            min_d = n.x * min.x; 
            max_d = n.x * max.x;
        } 
        
else 
        {
            min_d = n.x * max.x; 
            max_d = n.x * min.x;
        }
   
        
if (n.y > 0.0f) 
        {
            min_d += n.y * min.y; 
            max_d += n.y * max.y;
        } 
        
else 
        {
            min_d += n.y * max.y; 
            max_d += n.y * min.y;
        }
   
        
if (n.z > 0.0f) 
        {
            min_d += n.z * min.z; 
            max_d += n.z * max.z;
        } 
        
else 
        {
            min_d += n.z * max.z; 
            max_d += n.z * min.z;
        }
   
        
// check if we're already completely on the other side of the plane
   
    if(max_d <= plane_d)
            
return NO_INTERSECTION;
   
        
// perform standard raytrace equation using the frontmost corner point
   
    float t = (plane_d - min_d) / dot;
   
        
// Were we already penetrating?
   
    if(t < 0.0f)
            
return 0.0f;
   
        
// Return it, if t > L, then we didn't hit in time.
        // That's the condition that the caller should be checking for.
   
    return t;
    }
   
   
///////////////////////////////////// Global nonmember code ////////////////////////////////////////
   

   
//---------------------------------------------------------------------------
    // Check if two AABBs intersect, and return true if so.  Optionally return
    // the AABB of their intersection if an intersection is detected.
    //---------------------------------------------------------------------------
   
bool intersect_aabb(const cAABB3& box1, const cAABB3& box2, cAABB3* box_intersect)
    {
        
// check for no overlap
   
    if(box1.min.x > box2.max.x)    return false;
        
if(box1.max.x < box2.min.x)    return false;
        
if(box1.min.y > box2.max.y)    return false;
        
if(box1.max.y < box2.min.y)    return false;
        
if(box1.min.z > box2.max.z)    return false;
        
if(box1.max.z < box2.min.z)    return false;
   
        
// we have overlap, compute AABB of intersection, if they want it.
   
    if(box_intersect != NULL)
        {
            box_intersect->min.x = max(box1.min.x, box2.min.x);
            box_intersect->max.x = min(box1.max.x, box2.max.x);
            box_intersect->min.y = max(box1.min.y, box2.min.y);
            box_intersect->max.y = min(box1.max.y, box2.max.y);
            box_intersect->min.z = max(box1.min.z, box2.min.z);
            box_intersect->max.z = min(box1.max.z, box2.max.z);
        }
   
        
return true;
    }
   
   
//---------------------------------------------------------------------------
    // Return parametric point in time when a moving AABB collides
    // with a stationary AABB.  Returns > 1 if no intersection.
    //---------------------------------------------------------------------------
   
float intersect_moving_aabb(const cAABB3& stationary_aabb, const cAABB3& moving_aabb, const cVector3& d)
    {
        
// initialize interval to contain all the time under consideration
   
    float t_enter = 0.0f;
        
float t_leave = 1.0f;
   
        
// Compute interval of overlap on each dimension, and intersect this interval with the interval 
        // accumulated so far.  As soon as an empty interval is detected, return a negative result
        // (no intersection.)  In each case, we have to be careful for an infinite of empty interval on 
        // each dimension.
   
        // check x-axis
   

        
if(d.x == 0.0f)
        {
            
// empty or infinite interval on x
   
        if((stationary_aabb.min.x >= moving_aabb.max.x) || (stationary_aabb.max.x <= moving_aabb.min.x))
            {
                
// empty time interval, so no intersection.
   
            return NO_INTERSECTION;
            }
   
            
// inifinite time interval - no update necessary.
   
    }
        
else
        {
            
float one_over_d = 1.0f / d.x;    // divide once
   
            // compute time value when they begin and end overlapping
   
        float x_enter = (stationary_aabb.min.x - moving_aabb.max.x) * one_over_d;
            
float x_leave = (stationary_aabb.max.x - moving_aabb.min.x) * one_over_d;
            
            
// check for interval out of order
   
        if(x_enter > x_leave)
                swap(x_enter, x_leave);
   
            
// update interval
   
        if(x_enter > t_enter)    t_enter = x_enter;
            
if(x_leave > t_leave)    t_leave = x_leave;
   
            
// check if this resulted in empty interval
   
        if(t_enter > t_leave)
                
return NO_INTERSECTION;
        }
   
        
// check y-axis
   

        
if(d.y == 0.0f)
        {
            
// empty or infinite interval on y
   
        if((stationary_aabb.min.y >= moving_aabb.max.y) || (stationary_aabb.max.y <= moving_aabb.min.y))
            {
                
// empty time interval, so no intersection.
   
            return NO_INTERSECTION;
            }
   
            
// inifinite time interval - no update necessary.
   
    }
        
else
        {
            
float one_over_d = 1.0f / d.y;    // divide once
   
            // compute time value when they begin and end overlapping
   
        float y_enter = (stationary_aabb.min.y - moving_aabb.max.y) * one_over_d;
            
float y_leave = (stationary_aabb.max.y - moving_aabb.min.y) * one_over_d;
            
            
// check for interval out of order
   
        if(y_enter > y_leave)
                swap(y_enter, y_leave);
   
            
// update interval
   
        if(y_enter > t_enter)    t_enter = y_enter;
            
if(y_leave > t_leave)    t_leave = y_leave;
   
            
// check if this resulted in empty interval
   
        if(t_enter > t_leave)
                
return NO_INTERSECTION;
        }
   
        
// check z-axis
   

        
if(d.z == 0.0f)
        {
            
// empty or infinite interval on z
   
        if((stationary_aabb.min.z >= moving_aabb.max.z) || (stationary_aabb.max.z <= moving_aabb.min.z))
            {
                
// empty time interval, so no intersection.
   
            return NO_INTERSECTION;
            }
   
            
// inifinite time interval - no update necessary.
   
    }
        
else
        {
            
float one_over_d = 1.0f / d.z;    // divide once
   
            // compute time value when they begin and end overlapping
   
        float z_enter = (stationary_aabb.min.z - moving_aabb.max.z) * one_over_d;
            
float z_leave = (stationary_aabb.max.z - moving_aabb.min.z) * one_over_d;
            
            
// check for interval out of order
   
        if(z_enter > z_leave)
                swap(z_enter, z_leave);
   
            
// update interval
   
        if(z_enter > t_enter)    t_enter = z_enter;
            
if(z_leave > t_leave)    t_leave = z_leave;
   
            
// check if this resulted in empty interval
   
        if(t_enter > t_leave)
                
return NO_INTERSECTION;
        }
        
        
// Ok, we have an intersection.
        // Return the parametric point in time where the intersection occurs.
   
    return t_enter;
    }

posted on 2008-02-28 11:47 lovedday 閱讀(887) 評(píng)論(4)  編輯 收藏 引用

評(píng)論

# re: 幾何檢測(cè)(6) 2008-09-02 10:09 LoveAthrun2008

大哥,我想請(qǐng)問(wèn)您的這個(gè)教程是哪本書(shū)上的啊?書(shū)名叫什么?我想去買一本,請(qǐng)告之萬(wàn)分感謝,呵呵
您能否留下QQ,我有些問(wèn)題想請(qǐng)教您,呵呵  回復(fù)  更多評(píng)論   

# re: 幾何檢測(cè)(6) 2008-09-04 14:18 lovedday

《3D數(shù)學(xué)基礎(chǔ):圖形與游戲開(kāi)發(fā)》  回復(fù)  更多評(píng)論   

# re: 幾何檢測(cè)(6) 2008-09-06 10:10 LoveAthrun2008

非常感謝,呵呵,您貼的這幾個(gè)文章都是進(jìn)行3D游戲開(kāi)發(fā)必備的技術(shù),我從中受益非淺,謝謝  回復(fù)  更多評(píng)論   

# re: 幾何檢測(cè)(6) 2008-09-09 11:48 LoveAthrun2008

前輩,我想問(wèn)您一個(gè)問(wèn)題,我現(xiàn)在在用DX編一個(gè)小游戲,如果我的人物想從室外走進(jìn)一個(gè)房子,這個(gè)該怎么判定啊?人物在室外應(yīng)該是和房子的包圍盒進(jìn)行碰撞檢測(cè)吧?那房子的入口怎么辦?怎么做房子“外面”的碰撞啊?還有進(jìn)去后怎么和室內(nèi)的物體進(jìn)行碰撞檢測(cè)[包括上下樓和墻壁],謝謝~~~

如果您有類似文章或者DEMO的鏈接發(fā)給我也可以~~~  回復(fù)  更多評(píng)論   


只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


公告

導(dǎo)航

統(tǒng)計(jì)

常用鏈接

隨筆分類(178)

3D游戲編程相關(guān)鏈接

搜索

最新評(píng)論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美日韩视频在线观看一区二区三区| 欧美护士18xxxxhd| 国产日韩成人精品| 国产伦精品一区二区| 国产精品久久久久影院亚瑟| 国产精品日韩专区| 国产欧美在线看| 激情五月婷婷综合| 亚洲精品在线三区| 亚洲一区二区三区欧美| 欧美一区二区三区日韩| 久久天堂成人| 亚洲精品国偷自产在线99热| 亚洲国产精品va在线观看黑人| 国产亚洲欧美日韩在线一区| 国产欧美一区二区精品秋霞影院| 国产在线一区二区三区四区| 亚洲欧洲精品一区二区| 一本久道久久综合狠狠爱| 欧美一区二区| 欧美电影专区| 亚洲一区美女视频在线观看免费| 欧美一区综合| 欧美精品一区二区视频| 国产一区二区三区久久 | 欧美午夜电影在线| 国产视频久久久久| 亚洲韩日在线| 欧美影院视频| 91久久综合| 久久国产视频网| 欧美日韩视频在线一区二区| 国一区二区在线观看| 99国产成+人+综合+亚洲欧美| 欧美亚洲一级| 亚洲人体影院| 久久人人97超碰国产公开结果 | 亚洲国产欧美一区| 午夜精品福利一区二区蜜股av| 免费不卡在线视频| 亚洲一区二区三区四区在线观看| 久久亚洲国产成人| 国产精品一区二区三区观看 | 欧美色图五月天| 尤物在线精品| 亚久久调教视频| 亚洲精品黄色| 久久久久久久一区二区| 国产精品毛片高清在线完整版| 亚洲国产日韩欧美在线图片| 欧美影院视频| 亚洲自拍偷拍福利| 欧美性猛交99久久久久99按摩 | aa级大片欧美三级| 嫩模写真一区二区三区三州| 国产亚洲人成a一在线v站| 亚洲综合大片69999| 91久久国产精品91久久性色| 久久久久一本一区二区青青蜜月| 国产麻豆成人精品| 亚洲欧美日韩国产成人精品影院| 亚洲三级观看| 欧美日韩亚洲综合在线| 这里只有精品视频| 中文在线一区| 亚洲麻豆视频| 欧美日韩免费视频| aⅴ色国产欧美| 亚洲精品一区二区三区福利| 欧美aⅴ99久久黑人专区| 伊人夜夜躁av伊人久久| 玖玖综合伊人| 欧美高清视频| 日韩一级大片| 亚洲手机成人高清视频| 国产精品夜夜夜| 欧美专区在线观看一区| 欧美中日韩免费视频| 在线免费观看成人网| 欧美国产日韩精品| 欧美日韩午夜在线| 午夜视频久久久| 久久精品免费观看| 亚洲日本电影| 亚洲一区二区在线视频| 国产一区二区三区四区老人| 嫩草影视亚洲| 欧美精品一区三区在线观看| 亚洲欧美激情视频在线观看一区二区三区 | 国产欧美韩国高清| 久久亚洲精品一区二区| 欧美大片免费| 久久er99精品| 久久午夜激情| 一区二区三区高清视频在线观看| 亚洲欧美日韩区| 亚洲精品一区二区三区不| 亚洲午夜一区二区三区| 在线国产欧美| 亚洲女人天堂成人av在线| 亚洲国产精品悠悠久久琪琪| 亚洲图片欧美午夜| 亚洲电影在线看| 一区二区三区国产在线观看| 黄色一区二区三区四区| 日韩网站免费观看| 国内成人精品视频| 夜久久久久久| 亚洲精品美女91| 久久经典综合| 欧美一区二区成人| 欧美日韩免费在线观看| 牛牛精品成人免费视频| 欧美视频亚洲视频| 亚洲国产日本| 尤物九九久久国产精品的分类| 这里只有精品视频| 一本色道久久99精品综合| 久久久久国产精品人| 亚洲自拍偷拍网址| 欧美日韩美女在线| 欧美二区在线播放| 尤物九九久久国产精品的分类| 中文在线不卡| 国产精品99久久久久久久女警 | 一区二区在线视频| 亚洲欧美日韩一区二区| 亚洲新中文字幕| 欧美精品久久久久久久久老牛影院| 久久久水蜜桃av免费网站| 国产精品日韩久久久久| 一本一本大道香蕉久在线精品| 亚洲狼人精品一区二区三区| 久久夜色精品国产亚洲aⅴ | 久久精品在这里| 欧美日韩亚洲一区二区三区在线观看 | 日韩手机在线导航| 麻豆精品传媒视频| 欧美成人资源| 亚洲人成毛片在线播放| 久久久噜噜噜久噜久久| 玖玖玖免费嫩草在线影院一区| 国产又爽又黄的激情精品视频 | 欧美日韩1080p| 亚洲精选大片| 亚洲曰本av电影| 欧美亚州韩日在线看免费版国语版| 最近中文字幕日韩精品| 日韩视频亚洲视频| 欧美日本一区二区视频在线观看| 亚洲国产91| 宅男精品视频| 国产精品自在欧美一区| 亚洲免费在线看| 麻豆91精品| 亚洲裸体在线观看| 欧美午夜大胆人体| 亚洲图片欧美日产| 久久青青草综合| 亚洲日本成人在线观看| 欧美国产亚洲另类动漫| 日韩亚洲视频在线| 久久精品亚洲热| 亚洲国产精品久久人人爱蜜臀| 免费永久网站黄欧美| 99pao成人国产永久免费视频| 午夜精品久久久久久久白皮肤| 国产亚洲欧美激情| 男女激情视频一区| 亚洲免费在线观看| 免费日韩一区二区| 亚洲一本大道在线| 黄色精品一区二区| 国产精品videossex久久发布| 亚洲欧美美女| 亚洲成色777777女色窝| 午夜亚洲一区| 亚洲黄一区二区三区| 国产精品久久久久aaaa| 久久久亚洲人| 亚洲午夜激情网站| 鲁大师影院一区二区三区| 一本色道久久综合精品竹菊| 国产视频久久| 欧美三级视频在线| 久久精品国产免费观看| 在线综合+亚洲+欧美中文字幕| 免费成人av| 欧美一区二区三区精品电影| 亚洲精品色图| 亚洲一区二区伦理| 亚洲国产精品第一区二区| 欧美在线网址| 亚洲一区三区视频在线观看| 1024亚洲| 国产一区 二区 三区一级| 欧美精品一区二区三区久久久竹菊 | 玖玖在线精品| 欧美一区二区三区的| av成人动漫|