视锥裁剪

完成视锥裁剪请先阅读此文章:

http://www.flipcode.com/archives/Frustum_Culling.shtml


中文版翻译:

my.oschina.net/u/999400/blog/170062


编程源码,全部采用c++实现,可以找出在视锥范围内的点。用八叉树来进行搜索


vector3.h:

#ifndef PCL_MATH_VECTOR3D_H_
#define PCL_MATH_VECTOR3D_H_

#include <cmath>

/// 3D Vector.
class Vector3D {

public:
    Vector3D(double x1 = 0.0, double y1 = 0.0, double z1 = 0.0)
        : x(x1), y(y1), z(z1) {}

    bool operator ==(const Vector3D& rhs) const {
        return x == rhs.x && y == rhs.y && z == rhs.z;
    }

    bool operator !=(const Vector3D& rhs) const {
        return x != rhs.x || y != rhs.y || z != rhs.z;
    }

    const Vector3D& operator +=(const Vector3D& rhs) {
        x += rhs.x;
        y += rhs.y;
        z += rhs.z;
        return *this;
    }

    const Vector3D& operator -=(const Vector3D& rhs) {
        x -= rhs.x;
        y -= rhs.y;
        z -= rhs.z;
        return *this;
    }

    const Vector3D& operator *=(double value) {
        x *= value;
        y *= value;
        z *= value;
        return *this;
    }

    friend const Vector3D operator +(const Vector3D& lhs, const Vector3D& rhs) {
        return Vector3D(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z);
    }

    friend const Vector3D operator -(const Vector3D& lhs, const Vector3D& rhs) {
        return Vector3D(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z);
    }

    friend const Vector3D operator -(const Vector3D& rhs) {
        return Vector3D(-rhs.x, -rhs.y, -rhs.z);
    }

    friend const Vector3D operator *(double lhs, const Vector3D& rhs) {
        return Vector3D(lhs * rhs.x, lhs * rhs.y, lhs * rhs.z);
    }

    friend const Vector3D operator *(const Vector3D& lhs, double rhs) {
        return Vector3D(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs);
    }

    /**
     * Return the length of Vector2D.
     */
    double Length() const {
        return sqrt(x * x + y * y + z * z);
    }

    /**
     * Normalize the vector into the unit vector.
     */
    void Normalize() {
        double norm = Length();
        if (norm == 0.0) {
            x = y = z = 0.0;
            return;
        }

        norm = 1.0 / norm;
        x *= norm;
        y *= norm;
        z *= norm;
    }

    /**
     * Return the cross product of two vertors.
     */
    friend const Vector3D CrossProduct(const Vector3D& v1, const Vector3D& v2) {
        double x = v1.y * v2.z - v1.z * v2.y;
        double y = v1.z * v2.x - v1.x * v2.z;
        double z = v1.x * v2.y - v1.y * v2.x;
        return Vector3D(x, y, z);
    }

    /**
     * Return the dot product of two vertors.
     */
    friend double DotProduct(const Vector3D& v1, const Vector3D& v2) {
        return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
    }

    double x; /// X component of vector.
    double y; /// Y component of vector.
    double z; /// Z component of vector.
};

#endif

Vector4.h

#ifndef PCL_MATH_VECTOR4D_H_
#define PCL_MATH_VECTOR4D_H_

#include <cmath>
#include "Matrix.h"
/// 3D Vector.
class Vector4D {

public:
    Vector4D(double x1 = 0.0, double y1 = 0.0, double z1 = 0.0,double w1 = 0.0)
        : x(x1), y(y1), z(z1),w(w1) {}

    bool operator ==(const Vector4D& rhs) const {
		return x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w;
    }

    bool operator !=(const Vector4D& rhs) const {
		return x != rhs.x || y != rhs.y || z != rhs.z || w != rhs.w;
    }

    const Vector4D& operator +=(const Vector4D& rhs) {
        x += rhs.x;
        y += rhs.y;
        z += rhs.z;
		w += rhs.w;
        return *this;
    }

    const Vector4D& operator -=(const Vector4D& rhs) {
        x -= rhs.x;
        y -= rhs.y;
        z -= rhs.z;
		w -= rhs.w;
        return *this;
    }

    const Vector4D& operator *=(double value) {
        x *= value;
        y *= value;
        z *= value;
		w *= value;
        return *this;
    }

    friend const Vector4D operator +(const Vector4D& lhs, const Vector4D& rhs) {
		return Vector4D(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z,lhs.w + rhs.w);
    }

    friend const Vector4D operator -(const Vector4D& lhs, const Vector4D& rhs) {
        return Vector4D(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z,lhs.w - rhs.w);
    }

    friend const Vector4D operator -(const Vector4D& rhs) {
        return Vector4D(-rhs.x, -rhs.y, -rhs.z,-rhs.w);
    }

    friend const Vector4D operator *(double lhs, const Vector4D& rhs) {
		return Vector4D(lhs * rhs.x, lhs * rhs.y, lhs * rhs.z, lhs * rhs.w);
    }

    friend const Vector4D operator *(const Vector4D& lhs, double rhs) {
        return Vector4D(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs, lhs.w * rhs);
    }

    /**
     * Return the length of Vector2D.
     */
    double Length() const {
        return sqrt(x * x + y * y + z * z + w * w);
    }

    /**
     * Normalize the vector into the unit vector.
     */
    void Normalize() {
        double norm = Length();
        if (norm == 0.0) {
            x = y = z = 0.0;
            return;
        }

        norm = 1.0 / norm;
        x *= norm;
        y *= norm;
        z *= norm;
		w *= norm;
    }

	static Vector4D MultiPlyMatirx(Vector4D vec, Matrix m)
	{
		Vector4D tmp;
		tmp.x = vec.x * m.M11 + vec.y * m.M12 + vec.z * m.M13 + vec.w * m.M14;
		tmp.y = vec.x * m.M21 + vec.y * m.M22 + vec.z * m.M23 + vec.w * m.M24;
		tmp.z = vec.x * m.M31 + vec.y * m.M32 + vec.z * m.M33 + vec.w * m.M34;
		tmp.w = vec.x * m.M41 + vec.y * m.M42 + vec.z * m.M43 + vec.w * m.M44;

		tmp.x /= tmp.w;
		tmp.y /= tmp.w;
		tmp.z /= tmp.w;
		tmp.w = 1;
		return tmp;
	}

    double x; /// X component of vector.
    double y; /// Y component of vector.
    double z; /// Z component of vector.
	double w;
};

#endif
Matrix.h

#ifndef _MATRIX_H_
#define _MATRIX_H_

#include <cmath>
#pragma pack(push, 1)

struct Matrix
{
public:	
	 float M11;
	 float M12;
	 float M13;
	 float M14;
	 float M21;
	 float M22;
	 float M23;
	 float M24;
	 float M31;
	 float M32;
	 float M33;
	 float M34;
	 float M41;
	 float M42;
	 float M43;
	 float M44;


public:
	 Matrix()
	 {
	 }
	 Matrix(float M11, float M12, float M13, float M14, float M21, float M22, float M23, float M24, float M31, float M32, float M33, float M34, float M41, float M42, float M43, float M44)
		 :M11(M11),M12(M12),M13(M13),M14(M14),M21(M21),M22(M22),M23(M23),M24(M24),M31(M31),M32(M32),M33(M33),M34(M34),M41(M41),M42(M42),M43(M43),M44(M44)
	 {
	 }

	 Matrix(float *value)
	 {
		M11 = value[0];
		M12 = value[1];
		M13 = value[2];
		M14 = value[3];

		M21 = value[4];
		M22 = value[5];
		M23 = value[6];
		M24 = value[7];

		M31 = value[8];
		M32 = value[9];
		M33 = value[10];
		M34 = value[11];

		M41 = value[12];
		M42 = value[13];
		M43 = value[14];
		M44 = value[15];
		
		value->A
		//for(int i = 1;i < 5;i++)
		//{
		//	for(int j = 1;j < 5;j++)
		//	{
		//		A[i][j] = value[4*(i-1)+j-1];
		//	}
		//}

	 }

	 //求矩阵的逆

		 static void Invert( Matrix& value,  Matrix& result)
		{
			float b0 = (value.M31 * value.M42) - (value.M32 * value.M41);
			float b1 = (value.M31 * value.M43) - (value.M33 * value.M41);
			float b2 = (value.M34 * value.M41) - (value.M31 * value.M44);
			float b3 = (value.M32 * value.M43) - (value.M33 * value.M42);
			float b4 = (value.M34 * value.M42) - (value.M32 * value.M44);
			float b5 = (value.M33 * value.M44) - (value.M34 * value.M43);

			float d11 = value.M22 * b5 + value.M23 * b4 + value.M24 * b3;
			float d12 = value.M21 * b5 + value.M23 * b2 + value.M24 * b1;
			float d13 = value.M21 * -b4 + value.M22 * b2 + value.M24 * b0;
			float d14 = value.M21 * b3 + value.M22 * -b1 + value.M23 * b0;

			float det = value.M11 * d11 - value.M12 * d12 + value.M13 * d13 - value.M14 * d14;
			if (abs(det) == 0.0f)
			{
				result.M11 = 0;
				result.M12 = 0;
				result.M13 = 0;
				result.M14 = 0;
				result.M21 = 0;
				result.M22 = 0;
				result.M23 = 0;
				result.M24 = 0;
				result.M31 = 0;
				result.M32 = 0;
				result.M33 = 0;
				result.M34 = 0;
				result.M41 = 0;
				result.M42 = 0;
				result.M43 = 0;
				result.M44 = 0;
				
				return;
			}

			det = 1.0 / det;

			float a0 = (value.M11 * value.M22) - (value.M12 * value.M21);
			float a1 = (value.M11 * value.M23) - (value.M13 * value.M21);
			float a2 = (value.M14 * value.M21) - (value.M11 * value.M24);
			float a3 = (value.M12 * value.M23) - (value.M13 * value.M22);
			float a4 = (value.M14 * value.M22) - (value.M12 * value.M24);
			float a5 = (value.M13 * value.M24) - (value.M14 * value.M23);

			float d21 = value.M12 * b5 + value.M13 * b4 + value.M14 * b3;
			float d22 = value.M11 * b5 + value.M13 * b2 + value.M14 * b1;
			float d23 = value.M11 * -b4 + value.M12 * b2 + value.M14 * b0;
			float d24 = value.M11 * b3 + value.M12 * -b1 + value.M13 * b0;

			float d31 = value.M42 * a5 + value.M43 * a4 + value.M44 * a3;
			float d32 = value.M41 * a5 + value.M43 * a2 + value.M44 * a1;
			float d33 = value.M41 * -a4 + value.M42 * a2 + value.M44 * a0;
			float d34 = value.M41 * a3 + value.M42 * -a1 + value.M43 * a0;

			float d41 = value.M32 * a5 + value.M33 * a4 + value.M34 * a3;
			float d42 = value.M31 * a5 + value.M33 * a2 + value.M34 * a1;
			float d43 = value.M31 * -a4 + value.M32 * a2 + value.M34 * a0;
			float d44 = value.M31 * a3 + value.M32 * -a1 + value.M33 * a0;

			result.M11 = +d11 * det; result.M12 = -d21 * det; result.M13 = +d31 * det; result.M14 = -d41 * det;
			result.M21 = -d12 * det; result.M22 = +d22 * det; result.M23 = -d32 * det; result.M24 = +d42 * det;
			result.M31 = +d13 * det; result.M32 = -d23 * det; result.M33 = +d33 * det; result.M34 = -d43 * det;
			result.M41 = -d14 * det; result.M42 = +d24 * det; result.M43 = -d34 * det; result.M44 = +d44 * det;
	}
};
#pragma pack(pop)
#endif


Plane.h

#ifndef PCL_MATH_PLANE_H_
#define PCL_MATH_PLANE_H_

#include <cmath>
#include "Vector3.h"

/// 3D Vector.
class Plane{

        
public:
	Plane(){}
	// ժҪ:
    //     The distance of the plane along its normal from the origin.
	float D;
    //
    // ժҪ:
    //     The normal vector of the plane.
    Vector3D Normal;

	Plane(Vector3D Normal,float D)
	{
		this->Normal = Normal;
		this->D = D;
	}
public:
	void SetParams(Vector3D Normal,float D)
	{
		this->Normal = Normal;
		this->D = D;
	}
};

#endif


Sphere.h:

#ifndef _SPHERE_H_
#define _SPHERE_H_
#include <cmath>
#include "DataDefine.h"
#include "Vector3.h"

class Sphere
{
public:
	Sphere(){}
	Sphere(Bound3D bound)
	{
		center.x = (float)(bound.max_x + bound.min_x) / 2;
		center.y = (float)(bound.max_y + bound.min_y) / 2;
		center.z = (float)(bound.max_z + bound.min_z) / 2;
		radius = sqrt((bound.max_z - bound.min_z) * (bound.max_z - bound.min_z) + (bound.max_y - bound.min_y) * (bound.max_y - bound.min_y) + (bound.max_x - bound.min_x) * (bound.max_x - bound.min_x))/2;
	}

	void SetParams(Bound3D bound)
	{
		center.x = (float)(bound.max_x + bound.min_x) / 2;
		center.y = (float)(bound.max_y + bound.min_y) / 2;
		center.z = (float)(bound.max_z + bound.min_z) / 2;
		radius = sqrt((bound.max_z - bound.min_z) * (bound.max_z - bound.min_z) + (bound.max_y - bound.min_y) * (bound.max_y - bound.min_y) + (bound.max_x - bound.min_x) * (bound.max_x - bound.min_x))/2;
	}

	Sphere(Vector3D cen,float rad)
	{
		center = cen;
		radius = rad;
	}

	Vector3D Center()
	{
		return center;
	}
	float Radius()
	{
		return radius;
	}
private:
	Vector3D center;
	float radius;
};

#endif


最主要的程序,FrustumCulling.h

#ifndef _FRUSTUMCULLING_H_
#define _FRUSTUMCULLING_H_
#include <cmath>
#include "Plane.h"
#include "Vector3.h"
#include "Vector4.h"
#include "Matrix.h"
#include "Sphere.h"
#include "OTree.h"

#define PI 3.14159265
const int INSECT = 1;
const int OUTSECT = 2;
const int INTERSECT = 3;

class FrustumCulling
{

private:
	 Vector4D ConusPoint[8];
	 Vector4D Point[8];
	 Plane plane[6];

	 Sphere sphere;
	 float _NearPlane;
	 float _FarPlane;
	 float _Width;
	 float _Height;
	 PointsList _Points;
	 OTree* _Tree;
	 Matrix* _World;
	 
	 int flag;

public:
	FrustumCulling(){}

	int Get_Flag()
	{
		return flag;
	}
	//取得点云列表
    PointsList& GetPointsList()
	{
		return _Points;
	}


	void SetMatrix(float nearPlane,float farPlane,float width,float height,Matrix* world,OTree* tree)
	{
	  	this->_World = world;
 
		this->_NearPlane = nearPlane;
		this->_FarPlane = farPlane;
 
		this->_Width = width;
		this->_Height = height;
 
		this->_Tree = tree;
		ComputeConus();
		TransformConusPoint();
		ConstructPlane();
	}


	//计算视锥体的顶点坐标
	void ComputeConus()
	{
		float CameraZPoint = 2.0f;
		//nearPlnet point
		//leftdown
		
		Point[0].z = CameraZPoint - _NearPlane;
		Point[0].y = -_NearPlane * tan(PI / (3 * 2));
		Point[0].x = Point[0].y * (_Width / (float)_Height);
		Point[0].w = 1;

		//rightdown
		Point[1].z = Point[0].z;
		Point[1].y = Point[0].y;
		Point[1].x = -Point[0].x;
		Point[1].w = 1;

		//righttop;
		Point[2].z = Point[0].z;
		Point[2].y = -Point[0].y;
		Point[2].x = -Point[0].x;
		Point[2].w = 1;


		//lefttop
		Point[3].z = Point[0].z;
		Point[3].y = -Point[0].y;
		Point[3].x = Point[0].x;
		Point[3].w = 1;


		//farpoint
		//leftdown
		Point[4].z = CameraZPoint - _FarPlane;
		Point[4].y = -_FarPlane * tan(PI / (3 * 2));
		Point[4].x = Point[4].y * (_Width / (float)_Height);
		Point[4].w = 1;

		//rightdown
		Point[5].z = Point[4].z;
		Point[5].y = Point[4].y;
		Point[5].x = -Point[4].x;
		Point[5].w = 1;

		//righttop;
		Point[6].z = Point[4].z;
		Point[6].y = -Point[4].y;
		Point[6].x = -Point[4].x;
		Point[6].w = 1;

		//lefttop;
		Point[7].z = Point[4].z;
		Point[7].y = -Point[4].y;
		Point[7].x = Point[4].x;
		Point[7].w = 1;
	}

	//计算变换后的顶点坐标
	//镜头移动时猜进行重构
	void TransformConusPoint()
	{
		Matrix InverseOfWord;
		Matrix::Invert(*_World,InverseOfWord);
		for (int i = 0; i < 8; i++)
		{
			ConusPoint[i] = Vector4D::MultiPlyMatirx(Point[i], InverseOfWord);
		}
	}

	//为变换后的顶点坐标建立六个平面
	//镜头移动时猜进行重构
	void ConstructPlane()
	{
		//前平面
		Vector3D nearPoint1(ConusPoint[0].x, ConusPoint[0].y, ConusPoint[0].z);
		Vector3D nearPoint2(ConusPoint[1].x, ConusPoint[1].y, ConusPoint[1].z);
		Vector3D nearPoint3(ConusPoint[2].x, ConusPoint[2].y, ConusPoint[2].z);
		Vector3D rightDotnearPlane = nearPoint3 - nearPoint2;
		Vector3D leftDotnearPlane = nearPoint1 - nearPoint2;
		//计算叉乘
		Vector3D nearNormalVec = CrossProduct(leftDotnearPlane, rightDotnearPlane);
		nearNormalVec.Normalize();
		float d = -DotProduct(nearNormalVec, nearPoint1);
		plane[0].SetParams(nearNormalVec, d);
		//不能进行规范化plane[0].Normalize();

		//后平面
		Vector3D farPoint1(ConusPoint[4].x, ConusPoint[4].y, ConusPoint[4].z);
		Vector3D farPoint2(ConusPoint[5].x, ConusPoint[5].y, ConusPoint[5].z);
		Vector3D farPoint3(ConusPoint[6].x, ConusPoint[6].y, ConusPoint[6].z);
		Vector3D rightDotfarPlane = farPoint1 - farPoint2;
		Vector3D leftDotfarPlane = farPoint3 - farPoint2;
		//计算叉乘
		Vector3D farNormalVec = CrossProduct(leftDotfarPlane, rightDotfarPlane);
		farNormalVec.Normalize();
		d = -DotProduct(farNormalVec, farPoint1);
		plane[1].SetParams(farNormalVec, d);
		//plane[1].Normalize();

		//左平面
		Vector3D leftPoint1(ConusPoint[0].x, ConusPoint[0].y, ConusPoint[0].z);
		Vector3D leftPoint2(ConusPoint[4].x, ConusPoint[4].y, ConusPoint[4].z);
		Vector3D leftPoint3(ConusPoint[7].x, ConusPoint[7].y, ConusPoint[7].z);
		Vector3D rightDotleftPlane = leftPoint1 - leftPoint2;
		Vector3D leftDotleftPlane = leftPoint3 - leftPoint2;
		//计算叉乘
		Vector3D leftNormalVec = CrossProduct(leftDotleftPlane, rightDotleftPlane);
		leftNormalVec.Normalize();
		d = -DotProduct(leftNormalVec, leftPoint1);
		plane[2].SetParams(leftNormalVec, d);
		//plane[2].Normalize();

		//右平面
		Vector3D rightPoint1(ConusPoint[1].x, ConusPoint[1].y, ConusPoint[1].z);
		Vector3D rightPoint2(ConusPoint[5].x, ConusPoint[5].y, ConusPoint[5].z);
		Vector3D rightPoint3(ConusPoint[6].x, ConusPoint[6].y, ConusPoint[6].z);
		Vector3D leftDotrightPlane = rightPoint1 - rightPoint2;
		Vector3D rightDotrightPlane = rightPoint3 - rightPoint2;
		//计算叉乘
		Vector3D rightNormalVec = CrossProduct(leftDotrightPlane, rightDotrightPlane);
		rightNormalVec.Normalize();
		d = -DotProduct(rightNormalVec, rightPoint1);

		plane[3].SetParams(rightNormalVec, d);
		//plane[3].Normalize();

		//上平面
		Vector3D topPoint1(ConusPoint[3].x, ConusPoint[3].y, ConusPoint[3].z);
		Vector3D topPoint2(ConusPoint[2].x, ConusPoint[2].y, ConusPoint[2].z);
		Vector3D topPoint3(ConusPoint[6].x, ConusPoint[6].y, ConusPoint[6].z);
		Vector3D rightDottopPlane = topPoint3 - topPoint2;
		Vector3D leftDottopPlane = topPoint1 - topPoint2;
		//计算叉乘
		Vector3D topNormalVec = CrossProduct(leftDottopPlane, rightDottopPlane);
		topNormalVec.Normalize();
		d = -DotProduct(topNormalVec, topPoint1);
		plane[4].SetParams(topNormalVec, d);
		//plane[4].Normalize();

		//下平面
		Vector3D bottomPoint1(ConusPoint[0].x, ConusPoint[0].y, ConusPoint[0].z);
		Vector3D bottomPoint2(ConusPoint[1].x, ConusPoint[1].y, ConusPoint[1].z);
		Vector3D bottomPoint3(ConusPoint[5].x, ConusPoint[5].y, ConusPoint[5].z);
		Vector3D rightDotbottomPlane = bottomPoint1 - bottomPoint2;
		Vector3D leftDotbottomPlane = bottomPoint3 - bottomPoint2;
		//计算叉乘
		Vector3D bottomNormalVec = CrossProduct(leftDotbottomPlane, rightDotbottomPlane);
		bottomNormalVec.Normalize();
		d = -DotProduct(bottomNormalVec, bottomPoint1);
		plane[5].SetParams(bottomNormalVec, d);
		//plane[5].Normalize();
	}


	//先用球来进行判断
	//构造一个球体
	//sphere为私有变量
	void ConstructSphere(Bound3D& bound)
	{
		sphere.SetParams(bound);
	}

	int ContainsSphere(Sphere &refSphere)
	{
		//球体中心到某裁面的距离
		float fDistance;
		//遍历所有裁面并计算
		for (int i = 0; i < 6; ++i)
		{
			//计算距离
			fDistance = DotProduct(plane[i].Normal, refSphere.Center()) + plane[i].D;
			//如果距离小于负的球体半径,那么就是外离
			if (fDistance < -refSphere.Radius())
				return OUTSECT;
			//如果距离的绝对值小于球体半径,那么就是相交
			if (abs(fDistance) < refSphere.Radius())
				return INTERSECT;
		}
		//否则,就是内含
		return INSECT;
	}

	void GetVertics(Bound3D &bound, Vector3D vCorner[])
	{
		//1
		vCorner[0].x = (float)bound.min_x;
		vCorner[0].y = (float)bound.min_y;
		vCorner[0].z = (float)bound.min_z;


		//5
		vCorner[1].x = (float)bound.max_x;
		vCorner[1].y = (float)bound.min_y;
		vCorner[1].z = (float)bound.min_z;

		//6
		vCorner[2].x = (float)bound.max_x;
		vCorner[2].y = (float)bound.min_y;
		vCorner[2].z = (float)bound.max_z;

		//2
		vCorner[3].x = (float)bound.min_x;
		vCorner[3].y = (float)bound.min_y;
		vCorner[3].z = (float)bound.max_z;

		//3
		vCorner[4].x = (float)bound.min_x;
		vCorner[4].y = (float)bound.max_y;
		vCorner[4].z = (float)bound.min_z;

		//7
		vCorner[5].x = (float)bound.max_x;
		vCorner[5].y = (float)bound.max_y;
		vCorner[5].z = (float)bound.min_z;

		//8
		vCorner[6].x = (float)bound.max_x;
		vCorner[6].y = (float)bound.max_y;
		vCorner[6].z = (float)bound.max_z;

		//4
		vCorner[7].x = (float)bound.min_x;
		vCorner[7].y = (float)bound.max_y;
		vCorner[7].z = (float)bound.max_z;
	}



	int ContainsAaBox(Bound3D &bound)
	{

		Vector3D vCorner[8];
		int iTotalIn = 0;
		//获得所有顶点
		GetVertics(bound, vCorner);

		//测试6个面的8个顶点
		//如果所有点都在一个的背后,那就是外离
		//如果所有点都在每一个面的正面,就是内含
		for (int p = 0; p < 6; ++p)
		{
			int iInCount = 8;
			int iPtIn = 1;
			for (int i = 0; i < 8; ++i)
			{
				//测试这个点
				//if( plane[p].SideOfPlane(vCorner[i]) == BEHIND)
				//需要一个近似相等的量吗
				//if (Plane.DotCoordinate(plane[p], vCorner[i]) < 0)
				if( (DotProduct(plane[p].Normal, vCorner[i]) + plane[p].D) < 0)
				{
					iPtIn = 0;
					--iInCount;
				}
			}
			//所有点都在p面背后吗
			if (iInCount == 0)
				return OUTSECT; //外离
			//在面内的点有多少
			iTotalIn += iPtIn;
		}
		//如果iTotalIn是6,那么就都是在正面
		if (iTotalIn == 6)
			return INSECT; //内含
		return INTERSECT; //相交
	}

	bool TestPoint(Vector3D point)
	{

		for (int p = 0; p < 6; ++p)
		{
			//if (Plane.DotCoordinate(plane[p], point) < 0)
			if( (DotProduct(plane[p].Normal, point) + plane[p].D) < 0)
				return false;    
		}
		return true;
	}

	//对节点的递归处理
	void RecurseProcess(Bound3D &bound, bool bTestChildren = true)
	{
		if (bTestChildren)
		{
			switch(ContainsSphere(sphere))
			{
			case OUTSECT:
				flag = OUTSECT;
				return;

			case INSECT:
				flag = INSECT;
				bTestChildren = false;
				break;

			case INTERSECT:
				switch (ContainsAaBox(bound))
				{
				case INSECT:
					flag = INSECT;
					bTestChildren = false;
					break;
				case OUTSECT:
					flag = OUTSECT;
					return;
				}
				break;
			}
		}

		//判断代码:
		if (bTestChildren == false)
		{
			//在视锥体里面  所有的顶点都进行渲染 
		}
		else
		{
			flag = INTERSECT;
			Search(_Tree->GetHeadNode());
		}
	}
	
	void Search(ONode* node)
	{   //t->GetMaxLayer
		//终止递归的深度
		if (node == NULL)
			return;
		if(node->layerLevel > (_Tree->GetMaxLayer()))
		{
			return;
		}
		if(ContainsAaBox(node->bound) == INSECT)
		{
			_Tree->GetIdAllChildPoint(node->id,_Tree->GetMaxLayer(),_Points);
		}
		else if(ContainsAaBox(node->bound) == OUTSECT)
		{
			return;
		}
		else if(ContainsAaBox(node->bound) == INTERSECT)
		{
			Search(node->children[0]);
			Search(node->children[1]);
			Search(node->children[2]);
			Search(node->children[3]);
			Search(node->children[4]);
			Search(node->children[5]);
			Search(node->children[6]);
			Search(node->children[7]);
		}
	}
	
};
#endif


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值