bool TableObjectDetector<PointType> :: detect(PointCloudConstPtr cloud) {
	m_object_clusters.clear();
	initialize();

	// ---[ Convert the dataset
	cloud_ = cloud; 

	// ---[ Create the voxel grid
	pcl::PointCloud<Point> cloud_filtered;
	pass_.setInputCloud (cloud_);
	pass_.filter (cloud_filtered);
	cloud_filtered_.reset (new pcl::PointCloud<Point> (cloud_filtered));
	
	pcl::PointCloud<Point> cloud_downsampled;
	grid_.setInputCloud (cloud_filtered_);
	grid_.filter (cloud_downsampled);
	cloud_downsampled_.reset (new pcl::PointCloud<Point> (cloud_downsampled));

	if ((int) cloud_filtered_->points.size () < k_) {
		// This means that filtering returned very few points
		return false;
	}

	// ---[ Estimate the point normals
	pcl::PointCloud<pcl::Normal> cloud_normals;
	n3d_.setInputCloud (cloud_downsampled_);
	n3d_.compute (cloud_normals);
	cloud_normals_.reset (new pcl::PointCloud<pcl::Normal> (cloud_normals));
	
	// ---[ Perform segmentation
	pcl::PointIndices table_inliers; pcl::ModelCoefficients table_coefficients;
	seg_.setInputCloud (cloud_downsampled_);
	seg_.setInputNormals (cloud_normals_);
	seg_.segment (table_inliers, table_coefficients);
	table_inliers_.reset (new pcl::PointIndices (table_inliers));
	table_coefficients_.reset (new pcl::ModelCoefficients (table_coefficients));
	
	if (table_inliers_->indices.size () == 0)
		return false;

	m_plane = Plane (table_coefficients.values[0],
		table_coefficients.values[1],
		table_coefficients.values[2],
		table_coefficients.values[3]);

	// ---[ Extract the table
	pcl::PointCloud<Point> table_projected;
	proj_.setInputCloud (cloud_downsampled_);
	proj_.setIndices (table_inliers_);
	proj_.setModelCoefficients (table_coefficients_);
	proj_.filter (table_projected);
	table_projected_.reset (new pcl::PointCloud<Point> (table_projected));
	
	// ---[ Estimate the convex hull
	pcl::PointCloud<Point> table_hull;
	hull_.setDimension(2);
	hull_.setInputCloud (table_projected_);
	hull_.reconstruct (table_hull);
	table_hull_.reset (new pcl::PointCloud<Point> (table_hull));

	// ---[ Get the objects on top of the table
	pcl::PointIndices cloud_object_indices;
	prism_.setInputCloud (cloud_filtered_);
	prism_.setInputPlanarHull (table_hull_);
	prism_.segment (cloud_object_indices);
	
	pcl::PointCloud<Point> cloud_objects;
	pcl::ExtractIndices<Point> extract_object_indices;
	extract_object_indices.setInputCloud (cloud_filtered_);
	extract_object_indices.setIndices (boost::make_shared<const pcl::PointIndices> (cloud_object_indices));
	extract_object_indices.filter (cloud_objects);
	cloud_objects_.reset (new pcl::PointCloud<Point> (cloud_objects));
	
	if (cloud_objects.points.size () == 0)
		return false;

	// ---[ Downsample the points
#if 0
	pcl::PointCloud<Point> cloud_objects_downsampled;
	grid_objects_.setInputCloud (cloud_objects_);
	grid_objects_.filter (cloud_objects_downsampled);
	cloud_objects_downsampled_.reset (new pcl::PointCloud<Point> (cloud_objects_downsampled));

#endif
	
	// ---[ Split the objects into Euclidean clusters
	std::vector< pcl::PointIndices > object_clusters;
	cluster_.setInputCloud (cloud_objects_);
	cluster_.extract (object_clusters);
	
	
	for (size_t i = 0; i < object_clusters.size (); ++i) {
		std::vector <PointType, Eigen::aligned_allocator<PointType>> object_points;
		
		for (size_t k = 0; k < object_clusters[i].indices.size(); ++k) {
			int index = object_clusters[i].indices[k];
			Point p = cloud_objects_->points[index];
			object_points.push_back(p);
		}

		float min_dist_to_plane = FLT_MAX;
		for (int j = 0; j < object_points.size(); ++j) {
			pcl::PointXYZ pobj;
			pobj.x = object_points[j].x;
			pobj.y = object_points[j].y;
			pobj.z = object_points[j].z;

			min_dist_to_plane = std::min(plane().distanceToPlane(pobj), min_dist_to_plane);
		}

		if (min_dist_to_plane > m_max_dist_to_plane)
			continue;

		m_object_clusters.push_back(object_points);
	}
	
	return true;
}
Exemple #2
0
	Plane Plane::Normalize(const Plane plane)
	{
		float magnitude = 1.0f / Math::Sqrt((plane.Normal.X * plane.Normal.X) + (plane.Normal.Y * plane.Normal.Y) + (plane.Normal.Z * plane.Normal.Z));

		return Plane(plane.Normal.X * magnitude, plane.Normal.Y * magnitude, plane.Normal.Z * magnitude, plane.D * magnitude);
	}
Exemple #3
0
 Plane Plane::reversePlane() const
 {
   return Plane(-m_a, -m_b, -m_c, -m_d);
 }
Exemple #4
0
Variant::Variant(const Plane& p_plane) {

	type=PLANE;
	memnew_placement( _data._mem, Plane( p_plane ) );

}
Exemple #5
0
void Variant::reference(const Variant& p_variant) {

	
	if (this == &p_variant)
		return;
		
	clear();
		
	type=p_variant.type;
		
	switch( p_variant.type ) {
		case NIL: {
		
			// none
		} break;
		
		// atomic types 		
		case BOOL: {
		
			_data._bool=p_variant._data._bool;
		} break;
		case INT: {
		
			_data._int=p_variant._data._int;
		
		} break;
		case REAL: {
		
			_data._real=p_variant._data._real;
		
		} break;
		case STRING: {
		
			memnew_placement( _data._mem, String( *reinterpret_cast<const String*>(p_variant._data._mem) ) );
			
		} break;
		
		// math types
		
		case VECTOR2: {
		
			memnew_placement( _data._mem, Vector2( *reinterpret_cast<const Vector2*>(p_variant._data._mem) ) );
		
		} break;
		case RECT2: {
		
			memnew_placement( _data._mem, Rect2( *reinterpret_cast<const Rect2*>(p_variant._data._mem) ) );
		
		} break;
		case MATRIX32: {

			_data._matrix32 = memnew( Matrix32( *p_variant._data._matrix32 ) );

		} break;
		case VECTOR3: {
		
			memnew_placement( _data._mem, Vector3( *reinterpret_cast<const Vector3*>(p_variant._data._mem) ) );
		
		} break;
		case PLANE: {
		
			memnew_placement( _data._mem, Plane( *reinterpret_cast<const Plane*>(p_variant._data._mem) ) );
		
		} break;
/*		
		case QUAT: {
		
		
		} break;*/
		case _AABB: {
		
			_data._aabb = memnew( AABB( *p_variant._data._aabb ) );
		} break;
		case QUAT: {
		
			memnew_placement( _data._mem, Quat( *reinterpret_cast<const Quat*>(p_variant._data._mem) ) );
		
		} break;
		case MATRIX3: {
		
			_data._matrix3 = memnew( Matrix3( *p_variant._data._matrix3 ) );
		
		} break;
		case TRANSFORM: {
		
			_data._transform = memnew( Transform( *p_variant._data._transform ) );
		
		} break;
		
		// misc types		
		case COLOR: {
		
			memnew_placement( _data._mem, Color( *reinterpret_cast<const Color*>(p_variant._data._mem) ) );
		
		} break;
		case IMAGE: {
		
			_data._image = memnew( Image( *p_variant._data._image ) );
		
		} break;
		case _RID: {
		
			memnew_placement( _data._mem, RID( *reinterpret_cast<const RID*>(p_variant._data._mem) ) );
		} break;
		case OBJECT: {
		
			memnew_placement( _data._mem, ObjData( p_variant._get_obj() ) );
		} break;
		case NODE_PATH: {
		
			memnew_placement( _data._mem, NodePath( *reinterpret_cast<const NodePath*>(p_variant._data._mem) ) );
		
		} break;
		case INPUT_EVENT: {
			
			_data._input_event= memnew( InputEvent( *p_variant._data._input_event ) );
			
		} break;
		case DICTIONARY: {
			
			memnew_placement( _data._mem, Dictionary( *reinterpret_cast<const Dictionary*>(p_variant._data._mem) ) );
			
		} break;
		case ARRAY: {
			
			memnew_placement( _data._mem, Array ( *reinterpret_cast<const Array*>(p_variant._data._mem) ) );
			
		} break;
		
		// arrays
		case RAW_ARRAY: {
		
			memnew_placement( _data._mem, DVector<uint8_t> ( *reinterpret_cast<const DVector<uint8_t>*>(p_variant._data._mem) ) );
		
		} break;
		case INT_ARRAY: {
		
			memnew_placement( _data._mem, DVector<int> ( *reinterpret_cast<const DVector<int>*>(p_variant._data._mem) ) );
		
		} break;
		case REAL_ARRAY: {
		
			memnew_placement( _data._mem, DVector<real_t> ( *reinterpret_cast<const DVector<real_t>*>(p_variant._data._mem) ) );
		
		} break;
		case STRING_ARRAY: {
		
			memnew_placement( _data._mem, DVector<String> ( *reinterpret_cast<const DVector<String>*>(p_variant._data._mem) ) );
		
		} break;
		case VECTOR2_ARRAY: {

			memnew_placement( _data._mem, DVector<Vector2> ( *reinterpret_cast<const DVector<Vector2>*>(p_variant._data._mem) ) );

		} break;
		case VECTOR3_ARRAY: {
		
			memnew_placement( _data._mem, DVector<Vector3> ( *reinterpret_cast<const DVector<Vector3>*>(p_variant._data._mem) ) );
		
		} break;
		case COLOR_ARRAY: {
		
			memnew_placement( _data._mem, DVector<Color> ( *reinterpret_cast<const DVector<Color>*>(p_variant._data._mem) ) );
		
		} break;
		default: {}
	}		


}
Exemple #6
0
PlaneShape::PlaneShape() :
		Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_PLANE)) {

	set_plane(Plane(0, 1, 0, 0));
}
void CameraPerspective::CameraBound::calculate(const CameraPerspective* cam)
{
    // Calc frustum
    const mat44& matrix(cam->getViewProjection());
    m_Frustum.getPlaneForEdit(FrustumPlane_LeftClipPlane) = Plane(
        matrix(3, 0) + matrix(0, 0),
        matrix(3, 1) + matrix(0, 1),
        matrix(3, 2) + matrix(0, 2),
        matrix(3, 3) + matrix(0, 3));

    m_Frustum.getPlaneForEdit(FrustumPlane_RightClipPlane) = Plane(
        matrix(3, 0) - matrix(0, 0),
        matrix(3, 1) - matrix(0, 1),
        matrix(3, 2) - matrix(0, 2),
        matrix(3, 3) - matrix(0, 3));

    m_Frustum.getPlaneForEdit(FrustumPlane_TopClipPlane) = Plane(
        matrix(3, 0) - matrix(1, 0),
        matrix(3, 1) - matrix(1, 1),
        matrix(3, 2) - matrix(1, 2),
        matrix(3, 3) - matrix(1, 3));

    m_Frustum.getPlaneForEdit(FrustumPlane_BottomClipPlane) = Plane(
        matrix(3, 0) + matrix(1, 0),
        matrix(3, 1) + matrix(1, 1),
        matrix(3, 2) + matrix(1, 2),
        matrix(3, 3) + matrix(1, 3));

    m_Frustum.getPlaneForEdit(FrustumPlane_NearClipPlane) = Plane(
        matrix(3, 0) + matrix(2, 0),
        matrix(3, 1) + matrix(2, 1),
        matrix(3, 2) + matrix(2, 2),
        matrix(3, 3) + matrix(2, 3));

    m_Frustum.getPlaneForEdit(FrustumPlane_FarClipPlane) = Plane(
        matrix(3, 0) - matrix(2, 0),
        matrix(3, 1) - matrix(2, 1),
        matrix(3, 2) - matrix(2, 2),
        matrix(3, 3) - matrix(2, 3));


    // calculate sphere
    float nearClip(cam->getNearClip());
    float farClip(cam->getFarClip());
    float tanFov(tan(cam->getFov() * 0.5f));
    const vec3& pos(cam->getPosition());
    const vec3& look(cam->getLook());

    float viewLength(farClip - nearClip);

    float halfHeight(farClip * tanFov);
    float halfWidth(halfHeight * cam->getAspectRatio());

    vec3 halfWayPoint(0.0f, 0.0f, viewLength * 0.5f);
    vec3 farCorner(halfWidth, halfHeight, viewLength);
    vec3 diff(halfWayPoint - farCorner);

    m_Sphere.setRadius(length(diff));
    m_Sphere.setPosition(pos + look * halfWayPoint.z);


    // calculate cone
    float corner(sqrt(halfWidth * halfWidth + halfHeight * halfHeight));
    float fov(atan(corner / farClip) * 2.0f);

    m_Cone.setPosition(pos);
    m_Cone.setAxis(look);
    m_Cone.setFov(fov);
    m_Cone.setAxisLength(farClip);
}
Exemple #8
0
Plane MeshDataTool::get_vertex_tangent(int p_idx) const{

	ERR_FAIL_INDEX_V(p_idx,vertices.size(),Plane());
	return vertices[p_idx].tangent;

}
Exemple #9
0
Error MeshDataTool::create_from_surface(const Ref<Mesh>& p_mesh,int p_surface) {

	ERR_FAIL_COND_V(p_mesh.is_null(),ERR_INVALID_PARAMETER);

	ERR_FAIL_COND_V(p_mesh.is_null(),ERR_INVALID_PARAMETER);
	ERR_FAIL_COND_V(p_mesh->surface_get_primitive_type(p_surface)!=Mesh::PRIMITIVE_TRIANGLES,ERR_INVALID_PARAMETER);



	Array arrays = p_mesh->surface_get_arrays(p_surface);
	ERR_FAIL_COND_V( arrays.empty(), ERR_INVALID_PARAMETER );

	DVector<Vector3> varray = arrays[Mesh::ARRAY_VERTEX];

	int vcount = varray.size();
	ERR_FAIL_COND_V( vcount == 0, ERR_INVALID_PARAMETER);

	clear();
	format = p_mesh->surface_get_format(p_surface);
	material=p_mesh->surface_get_material(p_surface);

	DVector<Vector3>::Read vr = varray.read();

	DVector<Vector3>::Read nr;
	if (arrays[Mesh::ARRAY_NORMAL].get_type()!=Variant::NIL)
		nr = arrays[Mesh::ARRAY_NORMAL].operator DVector<Vector3>().read();

	DVector<real_t>::Read ta;
	if (arrays[Mesh::ARRAY_TANGENT].get_type()!=Variant::NIL)
		ta = arrays[Mesh::ARRAY_TANGENT].operator DVector<real_t>().read();

	DVector<Vector2>::Read uv;
	if (arrays[Mesh::ARRAY_TEX_UV].get_type()!=Variant::NIL)
		uv = arrays[Mesh::ARRAY_TEX_UV].operator DVector<Vector2>().read();
	DVector<Vector2>::Read uv2;
	if (arrays[Mesh::ARRAY_TEX_UV2].get_type()!=Variant::NIL)
		uv2 = arrays[Mesh::ARRAY_TEX_UV2].operator DVector<Vector2>().read();

	DVector<Color>::Read col;
	if (arrays[Mesh::ARRAY_COLOR].get_type()!=Variant::NIL)
		col = arrays[Mesh::ARRAY_COLOR].operator DVector<Color>().read();

	DVector<real_t>::Read bo;
	if (arrays[Mesh::ARRAY_BONES].get_type()!=Variant::NIL)
		bo = arrays[Mesh::ARRAY_BONES].operator DVector<real_t>().read();

	DVector<real_t>::Read we;
	if (arrays[Mesh::ARRAY_WEIGHTS].get_type()!=Variant::NIL)
		we = arrays[Mesh::ARRAY_WEIGHTS].operator DVector<real_t>().read();


	vertices.resize(vcount);

	for(int i=0;i<vcount;i++) {

		Vertex v;
		v.vertex=vr[i];
		if (nr.ptr())
			v.normal=nr[i];
		if (ta.ptr())
			v.tangent=Plane(ta[i*4+0],ta[i*4+1],ta[i*4+2],ta[i*4+3]);
		if (uv.ptr())
			v.uv=uv[i];
		if (uv2.ptr())
			v.uv2=uv2[i];
		if (col.ptr())
			v.color=col[i];

		if (we.ptr()) {

			v.weights.push_back(we[i*4+0]);
			v.weights.push_back(we[i*4+1]);
			v.weights.push_back(we[i*4+2]);
			v.weights.push_back(we[i*4+3]);
		}

		if (bo.ptr()) {

			v.bones.push_back(bo[i*4+0]);
			v.bones.push_back(bo[i*4+1]);
			v.bones.push_back(bo[i*4+2]);
			v.bones.push_back(bo[i*4+3]);
		}

		vertices[i]=v;


	}


	DVector<int> indices;

	if (arrays[Mesh::ARRAY_INDEX].get_type()!=Variant::NIL) {

		indices = arrays[Mesh::ARRAY_INDEX];
	} else {
		//make code simpler
		indices.resize(vcount);
		DVector<int>::Write iw=indices.write();
		for(int i=0;i<vcount;i++)
			iw[i]=i;
	}


	int icount=indices.size();
	DVector<int>::Read r = indices.read();


	Map<Point2i,int> edge_indices;

	for(int i=0;i<icount;i+=3) {

		Vertex*v[3]={ &vertices[r[i+0]], &vertices[r[i+1]], &vertices[r[i+2]] };

		int fidx=faces.size();
		Face face;

		for(int j=0;j<3;j++) {

			face.v[j]=r[i+j];

			Point2i edge(r[i+j],r[i+(j+1)%3]);
			if (edge.x > edge.y) {
				SWAP(edge.x,edge.y);
			}

			if (edge_indices.has(edge)) {
				face.edges[j]=edge_indices[edge];

			} else {
				face.edges[j]=edge_indices.size();
				edge_indices[edge]=face.edges[j];
				Edge e;
				e.vertex[0]=edge.x;
				e.vertex[1]=edge.y;
				edges.push_back(e);
			}

			edges[face.edges[j]].faces.push_back(fidx);
			v[j]->faces.push_back(fidx);
			v[j]->edges.push_back(face.edges[j]);
		}


		faces.push_back(face);
	}


	return OK;
}
bool CollisionSolverSW::solve_distance(const ShapeSW *p_shape_A,const Transform& p_transform_A,const ShapeSW *p_shape_B,const Transform& p_transform_B,Vector3& r_point_A,Vector3& r_point_B,const AABB& p_concave_hint,Vector3 *r_sep_axis) {

	if (p_shape_A->is_concave())
		return false;

	if (p_shape_B->get_type()==PhysicsServer::SHAPE_PLANE) {

		Vector3 a,b;
		bool col = solve_distance_plane(p_shape_B,p_transform_B,p_shape_A,p_transform_A,a,b);
		r_point_A=b;
		r_point_B=a;
		return !col;

	} else if (p_shape_B->is_concave()) {

		if (p_shape_A->is_concave())
			return false;


		const ConcaveShapeSW *concave_B=static_cast<const ConcaveShapeSW*>(p_shape_B);

		_ConcaveCollisionInfo cinfo;
		cinfo.transform_A=&p_transform_A;
		cinfo.shape_A=p_shape_A;
		cinfo.transform_B=&p_transform_B;
		cinfo.result_callback=NULL;
		cinfo.userdata=NULL;
		cinfo.swap_result=false;
		cinfo.collided=false;
		cinfo.collisions=0;
		cinfo.aabb_tests=0;
		cinfo.tested=false;

		Transform rel_transform = p_transform_A;
		rel_transform.origin-=p_transform_B.origin;

		//quickly compute a local AABB

		bool use_cc_hint=p_concave_hint!=AABB();
		AABB cc_hint_aabb;
		if (use_cc_hint) {
			cc_hint_aabb=p_concave_hint;
			cc_hint_aabb.pos-=p_transform_B.origin;
		}

		AABB local_aabb;
		for(int i=0;i<3;i++) {

		     Vector3 axis( p_transform_B.basis.get_axis(i) );
		     float axis_scale = 1.0/axis.length();
		     axis*=axis_scale;

		     float smin,smax;

		     if (use_cc_hint) {
			     cc_hint_aabb.project_range_in_plane(Plane(axis,0),smin,smax);
		     } else {
			     p_shape_A->project_range(axis,rel_transform,smin,smax);
		      }

		     smin*=axis_scale;
		     smax*=axis_scale;

		     local_aabb.pos[i]=smin;
		     local_aabb.size[i]=smax-smin;
		}


		concave_B->cull(local_aabb,concave_distance_callback,&cinfo);
		if (!cinfo.collided) {
//			print_line(itos(cinfo.tested));
			r_point_A=cinfo.close_A;
			r_point_B=cinfo.close_B;

		}

		//print_line("DIST AABB TESTS: "+itos(cinfo.aabb_tests));

		return !cinfo.collided;
	} else {

		return gjk_epa_calculate_distance(p_shape_A,p_transform_A,p_shape_B,p_transform_B,r_point_A,r_point_B); //should pass sepaxis..
	}


	return false;
}
Exemple #11
0
        void Frustum::rebuild()
        {
            // Rebuilds the clipping planes as well as the near and far corners.

            const Math::Matrix4x4 viewProjMatrix = m_ProjMatrix * m_ViewMatrix;
            const Math::Matrix4x4 invViewProjMatrix = viewProjMatrix.getInverse();

            //------------------------------------------------------------
            // Set corners in NDC-space

            Math::Vector4f nearLowerLeft  = Math::Vector4f(-1.0f, -1.0f, 0.0f, 1.0f);
            Math::Vector4f nearLowerRight = Math::Vector4f( 1.0f, -1.0f, 0.0f, 1.0f);
            Math::Vector4f nearUpperRight = Math::Vector4f( 1.0f,  1.0f, 0.0f, 1.0f);
            Math::Vector4f nearUpperLeft  = Math::Vector4f(-1.0f,  1.0f, 0.0f, 1.0f);

            Math::Vector4f farLowerLeft   = Math::Vector4f(-1.0f, -1.0f, 1.0f, 1.0f);
            Math::Vector4f farLowerRight  = Math::Vector4f( 1.0f, -1.0f, 1.0f, 1.0f);
            Math::Vector4f farUpperRight  = Math::Vector4f( 1.0f,  1.0f, 1.0f, 1.0f);
            Math::Vector4f farUpperLeft   = Math::Vector4f(-1.0f,  1.0f, 1.0f, 1.0f);
            
            //------------------------------------------------------------
            // Mutiply by inverse view-projection matrix

            nearLowerLeft  = invViewProjMatrix * nearLowerLeft;
            nearLowerRight = invViewProjMatrix * nearLowerRight;
            nearUpperRight = invViewProjMatrix * nearUpperRight;
            nearUpperLeft  = invViewProjMatrix * nearUpperLeft;

            farLowerLeft   = invViewProjMatrix * farLowerLeft;
            farLowerRight  = invViewProjMatrix * farLowerRight;
            farUpperRight  = invViewProjMatrix * farUpperRight;
            farUpperLeft   = invViewProjMatrix * farUpperLeft;
            
            //------------------------------------------------------------
            // Divide by w term

            nearLowerLeft  /= nearLowerLeft.w;
            nearLowerRight /= nearLowerRight.w;
            nearUpperRight /= nearUpperRight.w;
            nearUpperLeft  /= nearUpperLeft.w;
            
            farLowerLeft   /= farLowerLeft.w;
            farLowerRight  /= farLowerRight.w;
            farUpperRight  /= farUpperRight.w;
            farUpperLeft   /= farUpperLeft.w;

            //------------------------------------------------------------
            // Set world-space corners

            m_NearCorners[0] = nearLowerLeft.xyz();
            m_NearCorners[1] = nearLowerRight.xyz();
            m_NearCorners[2] = nearUpperRight.xyz();
            m_NearCorners[3] = nearUpperLeft.xyz();

            m_FarCorners[0]  = farLowerLeft.xyz();
            m_FarCorners[1]  = farLowerRight.xyz();
            m_FarCorners[2]  = farUpperRight.xyz();
            m_FarCorners[3]  = farUpperLeft.xyz();

            //------------------------------------------------------------
            // Build bounding planes

            m_LeftPlane   = Plane(m_NearCorners[0], m_NearCorners[3], m_FarCorners[3]);
            m_TopPlane    = Plane(m_NearCorners[3], m_NearCorners[2], m_FarCorners[2]);
            m_RightPlane  = Plane(m_NearCorners[1], m_FarCorners[1],  m_FarCorners[2]);
            m_BottomPlane = Plane(m_NearCorners[0], m_FarCorners[0],  m_FarCorners[1]);
            m_NearPlane   = Plane(m_NearCorners[0], m_NearCorners[1], m_NearCorners[2]);
            m_FarPlane    = Plane(m_FarCorners[0],  m_FarCorners[3],  m_FarCorners[2]);
        }
Exemple #12
0
    //-----------------------------------------------------------------------
    const PlaneBoundedVolumeList& Light::_getFrustumClipVolumes(const Camera* const cam) const
    {

        // Homogenous light position
        Vector4 lightPos = getAs4DVector();
        // 3D version (not the same as _getDerivedPosition, is -direction for
        // directional lights)
        Vector3 lightPos3 = Vector3(lightPos.x, lightPos.y, lightPos.z);

        const Vector3 *clockwiseVerts[4];

        // Get worldspace frustum corners
        const Vector3* corners = cam->getWorldSpaceCorners();
        int windingPt0 = cam->isReflected() ? 1 : 0;
        int windingPt1 = cam->isReflected() ? 0 : 1;

        bool infiniteViewDistance = (cam->getFarClipDistance() == 0);

        Vector3 notSoFarCorners[4];
        if(infiniteViewDistance)
        {
            Vector3 camPosition = cam->getRealPosition();
            notSoFarCorners[0] = corners[0] + corners[0] - camPosition;
            notSoFarCorners[1] = corners[1] + corners[1] - camPosition;
            notSoFarCorners[2] = corners[2] + corners[2] - camPosition;
            notSoFarCorners[3] = corners[3] + corners[3] - camPosition;
        }

        mFrustumClipVolumes.clear();
        for (unsigned short n = 0; n < 6; ++n)
        {
            // Skip far plane if infinite view frustum
            if (infiniteViewDistance && n == FRUSTUM_PLANE_FAR)
                continue;

            const Plane& plane = cam->getFrustumPlane(n);
            Vector4 planeVec(plane.normal.x, plane.normal.y, plane.normal.z, plane.d);
            // planes face inwards, we need to know if light is on negative side
            Real d = planeVec.dotProduct(lightPos);
            if (d < -1e-06)
            {
                // Ok, this is a valid one
                // clockwise verts mean we can cross-product and always get normals
                // facing into the volume we create

                mFrustumClipVolumes.push_back(PlaneBoundedVolume());
                PlaneBoundedVolume& vol = mFrustumClipVolumes.back();
                switch(n)
                {
                case(FRUSTUM_PLANE_NEAR):
                    clockwiseVerts[0] = corners + 3;
                    clockwiseVerts[1] = corners + 2;
                    clockwiseVerts[2] = corners + 1;
                    clockwiseVerts[3] = corners + 0;
                    break;
                case(FRUSTUM_PLANE_FAR):
                    clockwiseVerts[0] = corners + 7;
                    clockwiseVerts[1] = corners + 6;
                    clockwiseVerts[2] = corners + 5;
                    clockwiseVerts[3] = corners + 4;
                    break;
                case(FRUSTUM_PLANE_LEFT):
                    clockwiseVerts[0] = infiniteViewDistance ? notSoFarCorners + 1 : corners + 5;
                    clockwiseVerts[1] = corners + 1;
                    clockwiseVerts[2] = corners + 2;
                    clockwiseVerts[3] = infiniteViewDistance ? notSoFarCorners + 2 : corners + 6;
                    break;
                case(FRUSTUM_PLANE_RIGHT):
                    clockwiseVerts[0] = infiniteViewDistance ? notSoFarCorners + 3 : corners + 7;
                    clockwiseVerts[1] = corners + 3;
                    clockwiseVerts[2] = corners + 0;
                    clockwiseVerts[3] = infiniteViewDistance ? notSoFarCorners + 0 : corners + 4;
                    break;
                case(FRUSTUM_PLANE_TOP):
                    clockwiseVerts[0] = infiniteViewDistance ? notSoFarCorners + 0 : corners + 4;
                    clockwiseVerts[1] = corners + 0;
                    clockwiseVerts[2] = corners + 1;
                    clockwiseVerts[3] = infiniteViewDistance ? notSoFarCorners + 1 : corners + 5;
                    break;
                case(FRUSTUM_PLANE_BOTTOM):
                    clockwiseVerts[0] = infiniteViewDistance ? notSoFarCorners + 2 : corners + 6;
                    clockwiseVerts[1] = corners + 2;
                    clockwiseVerts[2] = corners + 3;
                    clockwiseVerts[3] = infiniteViewDistance ? notSoFarCorners + 3 : corners + 7;
                    break;
                };

                // Build a volume
                // Iterate over world points and form side planes
                Vector3 normal;
                Vector3 lightDir;
                unsigned int infiniteViewDistanceInt = infiniteViewDistance ? 1 : 0;
                for (unsigned int i = 0; i < 4 - infiniteViewDistanceInt; ++i)
                {
                    // Figure out light dir
                    lightDir = lightPos3 - (*(clockwiseVerts[i]) * lightPos.w);
                    Vector3 edgeDir = *(clockwiseVerts[(i+windingPt1)%4]) - *(clockwiseVerts[(i+windingPt0)%4]);
                    // Cross with anticlockwise corner, therefore normal points in
                    normal = edgeDir.crossProduct(lightDir);
                    normal.normalise();
                    vol.planes.push_back(Plane(normal, *(clockwiseVerts[i])));
                }

                // Now do the near plane (this is the plane of the side we're 
                // talking about, with the normal inverted (d is already interpreted as -ve)
                vol.planes.push_back( Plane(-plane.normal, plane.d) );

                // Finally, for a point/spot light we can add a sixth plane
                // This prevents false positives from behind the light
                if (mLightType != LT_DIRECTIONAL)
                {
                    // re-use our own plane normal
                    vol.planes.push_back(Plane(plane.normal, lightPos3));
                }
            }
        }

        return mFrustumClipVolumes;
    }
Exemple #13
0
    //-----------------------------------------------------------------------
    const PlaneBoundedVolume& Light::_getNearClipVolume(const Camera* const cam) const
    {
        // First check if the light is close to the near plane, since
        // in this case we have to build a degenerate clip volume
        mNearClipVolume.planes.clear();
        mNearClipVolume.outside = Plane::NEGATIVE_SIDE;

        Real n = cam->getNearClipDistance();
        // Homogenous position
        Vector4 lightPos = getAs4DVector();
        // 3D version (not the same as _getDerivedPosition, is -direction for
        // directional lights)
        Vector3 lightPos3 = Vector3(lightPos.x, lightPos.y, lightPos.z);

        // Get eye-space light position
        // use 4D vector so directional lights still work
        Vector4 eyeSpaceLight = cam->getViewMatrix() * lightPos;
        // Find distance to light, project onto -Z axis
        Real d = eyeSpaceLight.dotProduct(
            Vector4(0, 0, -1, -n) );
        #define THRESHOLD 1e-6
        if (d > THRESHOLD || d < -THRESHOLD)
        {
            // light is not too close to the near plane
            // First find the worldspace positions of the corners of the viewport
            const Vector3 *corner = cam->getWorldSpaceCorners();
            int winding = (d < 0) ^ cam->isReflected() ? +1 : -1;
            // Iterate over world points and form side planes
            Vector3 normal;
            Vector3 lightDir;
            for (unsigned int i = 0; i < 4; ++i)
            {
                // Figure out light dir
                lightDir = lightPos3 - (corner[i] * lightPos.w);
                // Cross with anticlockwise corner, therefore normal points in
                normal = (corner[i] - corner[(i+winding)%4])
                    .crossProduct(lightDir);
                normal.normalise();
                mNearClipVolume.planes.push_back(Plane(normal, corner[i]));
            }

            // Now do the near plane plane
            normal = cam->getFrustumPlane(FRUSTUM_PLANE_NEAR).normal;
            if (d < 0)
            {
                // Behind near plane
                normal = -normal;
            }
            const Vector3& cameraPos = cam->getDerivedPosition();
            mNearClipVolume.planes.push_back(Plane(normal, cameraPos));

            // Finally, for a point/spot light we can add a sixth plane
            // This prevents false positives from behind the light
            if (mLightType != LT_DIRECTIONAL)
            {
                // Direction from light perpendicular to near plane
                mNearClipVolume.planes.push_back(Plane(-normal, lightPos3));
            }
        }
        else
        {
            // light is close to being on the near plane
            // degenerate volume including the entire scene 
            // we will always require light / dark caps
            mNearClipVolume.planes.push_back(Plane(Vector3::UNIT_Z, -n));
            mNearClipVolume.planes.push_back(Plane(-Vector3::UNIT_Z, n));
        }

        return mNearClipVolume;
    }
Exemple #14
0
Plane AABB::FacePlane(int faceIndex) const
{
	assume(0 <= faceIndex && faceIndex <= 5);
	return Plane(FaceCenterPoint(faceIndex), FaceNormal(faceIndex));
}
Exemple #15
0
void BakedLight::_plot_face(int p_idx, int p_level, const Vector3 *p_vtx, const Vector2 *p_uv, const MaterialCache &p_material, const Rect3 &p_aabb) {

	if (p_level == cell_subdiv - 1) {
		//plot the face by guessing it's albedo and emission value

		//find best axis to map to, for scanning values
		int closest_axis;
		float closest_dot;

		Vector3 normal = Plane(p_vtx[0], p_vtx[1], p_vtx[2]).normal;

		for (int i = 0; i < 3; i++) {

			Vector3 axis;
			axis[i] = 1.0;
			float dot = ABS(normal.dot(axis));
			if (i == 0 || dot > closest_dot) {
				closest_axis = i;
				closest_dot = dot;
			}
		}

		Vector3 axis;
		axis[closest_axis] = 1.0;
		Vector3 t1;
		t1[(closest_axis + 1) % 3] = 1.0;
		Vector3 t2;
		t2[(closest_axis + 2) % 3] = 1.0;

		t1 *= p_aabb.size[(closest_axis + 1) % 3] / float(color_scan_cell_width);
		t2 *= p_aabb.size[(closest_axis + 2) % 3] / float(color_scan_cell_width);

		Color albedo_accum;
		Color emission_accum;
		float alpha = 0.0;

		//map to a grid average in the best axis for this face
		for (int i = 0; i < color_scan_cell_width; i++) {

			Vector3 ofs_i = float(i) * t1;

			for (int j = 0; j < color_scan_cell_width; j++) {

				Vector3 ofs_j = float(j) * t2;

				Vector3 from = p_aabb.pos + ofs_i + ofs_j;
				Vector3 to = from + t1 + t2 + axis * p_aabb.size[closest_axis];
				Vector3 half = (to - from) * 0.5;

				//is in this cell?
				if (!fast_tri_box_overlap(from + half, half, p_vtx)) {
					continue; //face does not span this cell
				}

				//go from -size to +size*2 to avoid skipping collisions
				Vector3 ray_from = from + (t1 + t2) * 0.5 - axis * p_aabb.size[closest_axis];
				Vector3 ray_to = ray_from + axis * p_aabb.size[closest_axis] * 2;

				Vector3 intersection;

				if (!Geometry::ray_intersects_triangle(ray_from, ray_to, p_vtx[0], p_vtx[1], p_vtx[2], &intersection)) {
					//no intersect? look in edges

					float closest_dist = 1e20;
					for (int j = 0; j < 3; j++) {
						Vector3 c;
						Vector3 inters;
						Geometry::get_closest_points_between_segments(p_vtx[j], p_vtx[(j + 1) % 3], ray_from, ray_to, inters, c);
						float d = c.distance_to(intersection);
						if (j == 0 || d < closest_dist) {
							closest_dist = d;
							intersection = inters;
						}
					}
				}

				Vector2 uv = get_uv(intersection, p_vtx, p_uv);

				int uv_x = CLAMP(Math::fposmod(uv.x, 1.0f) * bake_texture_size, 0, bake_texture_size - 1);
				int uv_y = CLAMP(Math::fposmod(uv.y, 1.0f) * bake_texture_size, 0, bake_texture_size - 1);

				int ofs = uv_y * bake_texture_size + uv_x;
				albedo_accum.r += p_material.albedo[ofs].r;
				albedo_accum.g += p_material.albedo[ofs].g;
				albedo_accum.b += p_material.albedo[ofs].b;
				albedo_accum.a += p_material.albedo[ofs].a;

				emission_accum.r += p_material.emission[ofs].r;
				emission_accum.g += p_material.emission[ofs].g;
				emission_accum.b += p_material.emission[ofs].b;
				alpha += 1.0;
			}
		}

		if (alpha == 0) {
			//could not in any way get texture information.. so use closest point to center

			Face3 f(p_vtx[0], p_vtx[1], p_vtx[2]);
			Vector3 inters = f.get_closest_point_to(p_aabb.pos + p_aabb.size * 0.5);

			Vector2 uv = get_uv(inters, p_vtx, p_uv);

			int uv_x = CLAMP(Math::fposmod(uv.x, 1.0f) * bake_texture_size, 0, bake_texture_size - 1);
			int uv_y = CLAMP(Math::fposmod(uv.y, 1.0f) * bake_texture_size, 0, bake_texture_size - 1);

			int ofs = uv_y * bake_texture_size + uv_x;

			alpha = 1.0 / (color_scan_cell_width * color_scan_cell_width);

			albedo_accum.r = p_material.albedo[ofs].r * alpha;
			albedo_accum.g = p_material.albedo[ofs].g * alpha;
			albedo_accum.b = p_material.albedo[ofs].b * alpha;
			albedo_accum.a = p_material.albedo[ofs].a * alpha;

			emission_accum.r = p_material.emission[ofs].r * alpha;
			emission_accum.g = p_material.emission[ofs].g * alpha;
			emission_accum.b = p_material.emission[ofs].b * alpha;

			zero_alphas++;
		} else {

			float accdiv = 1.0 / (color_scan_cell_width * color_scan_cell_width);
			alpha *= accdiv;

			albedo_accum.r *= accdiv;
			albedo_accum.g *= accdiv;
			albedo_accum.b *= accdiv;
			albedo_accum.a *= accdiv;

			emission_accum.r *= accdiv;
			emission_accum.g *= accdiv;
			emission_accum.b *= accdiv;
		}

		//put this temporarily here, corrected in a later step
		bake_cells_write[p_idx].albedo[0] += albedo_accum.r;
		bake_cells_write[p_idx].albedo[1] += albedo_accum.g;
		bake_cells_write[p_idx].albedo[2] += albedo_accum.b;
		bake_cells_write[p_idx].light[0] += emission_accum.r;
		bake_cells_write[p_idx].light[1] += emission_accum.g;
		bake_cells_write[p_idx].light[2] += emission_accum.b;
		bake_cells_write[p_idx].alpha += alpha;

		static const Vector3 side_normals[6] = {
			Vector3(-1, 0, 0),
			Vector3(1, 0, 0),
			Vector3(0, -1, 0),
			Vector3(0, 1, 0),
			Vector3(0, 0, -1),
			Vector3(0, 0, 1),
		};

		for (int i = 0; i < 6; i++) {
			if (normal.dot(side_normals[i]) > CMP_EPSILON) {
				bake_cells_write[p_idx].used_sides |= (1 << i);
			}
		}

	} else {
		//go down
		for (int i = 0; i < 8; i++) {

			Rect3 aabb = p_aabb;
			aabb.size *= 0.5;

			if (i & 1)
				aabb.pos.x += aabb.size.x;
			if (i & 2)
				aabb.pos.y += aabb.size.y;
			if (i & 4)
				aabb.pos.z += aabb.size.z;

			{
				Rect3 test_aabb = aabb;
				//test_aabb.grow_by(test_aabb.get_longest_axis_size()*0.05); //grow a bit to avoid numerical error in real-time
				Vector3 qsize = test_aabb.size * 0.5; //quarter size, for fast aabb test

				if (!fast_tri_box_overlap(test_aabb.pos + qsize, qsize, p_vtx)) {
					//if (!Face3(p_vtx[0],p_vtx[1],p_vtx[2]).intersects_aabb2(aabb)) {
					//does not fit in child, go on
					continue;
				}
			}

			if (bake_cells_write[p_idx].childs[i] == CHILD_EMPTY) {
				//sub cell must be created

				if (bake_cells_used == (1 << bake_cells_alloc)) {
					//exhausted cells, creating more space
					bake_cells_alloc++;
					bake_cells_write = PoolVector<BakeCell>::Write();
					bake_cells.resize(1 << bake_cells_alloc);
					bake_cells_write = bake_cells.write();
				}

				bake_cells_write[p_idx].childs[i] = bake_cells_used;
				bake_cells_level_used[p_level + 1]++;
				bake_cells_used++;
			}

			_plot_face(bake_cells_write[p_idx].childs[i], p_level + 1, p_vtx, p_uv, p_material, aabb);
		}
	}
}
Object* Primitives::Plane(int iSegments, float fRadius)
{
	return Plane(iSegments, iSegments, fRadius, fRadius);
}
Exemple #17
0
void GIProbe::_plot_face(int p_idx, int p_level,int p_x,int p_y,int p_z, const Vector3 *p_vtx, const Vector2* p_uv, const Baker::MaterialCache& p_material, const Rect3 &p_aabb,Baker *p_baker) {



	if (p_level==p_baker->cell_subdiv-1) {
		//plot the face by guessing it's albedo and emission value

		//find best axis to map to, for scanning values
		int closest_axis;
		float closest_dot;

		Vector3 normal = Plane(p_vtx[0],p_vtx[1],p_vtx[2]).normal;

		for(int i=0;i<3;i++) {

			Vector3 axis;
			axis[i]=1.0;
			float dot=ABS(normal.dot(axis));
			if (i==0 || dot>closest_dot) {
				closest_axis=i;
				closest_dot=dot;
			}
		}

		Vector3 axis;
		axis[closest_axis]=1.0;
		Vector3 t1;
		t1[(closest_axis+1)%3]=1.0;
		Vector3 t2;
		t2[(closest_axis+2)%3]=1.0;

		t1*=p_aabb.size[(closest_axis+1)%3]/float(color_scan_cell_width);
		t2*=p_aabb.size[(closest_axis+2)%3]/float(color_scan_cell_width);

		Color albedo_accum;
		Color emission_accum;
		Vector3 normal_accum;

		float alpha=0.0;

		//map to a grid average in the best axis for this face
		for(int i=0;i<color_scan_cell_width;i++) {

			Vector3 ofs_i=float(i)*t1;

			for(int j=0;j<color_scan_cell_width;j++) {

				Vector3 ofs_j=float(j)*t2;

				Vector3 from = p_aabb.pos+ofs_i+ofs_j;
				Vector3 to = from + t1 + t2 + axis * p_aabb.size[closest_axis];
				Vector3 half = (to-from)*0.5;

				//is in this cell?
				if (!fast_tri_box_overlap(from+half,half,p_vtx)) {
					continue; //face does not span this cell
				}

				//go from -size to +size*2 to avoid skipping collisions
				Vector3 ray_from = from + (t1+t2)*0.5 - axis * p_aabb.size[closest_axis];
				Vector3 ray_to = ray_from + axis * p_aabb.size[closest_axis]*2;

				Vector3 intersection;

				if (!Geometry::ray_intersects_triangle(ray_from,ray_to,p_vtx[0],p_vtx[1],p_vtx[2],&intersection)) {
					//no intersect? look in edges

					float closest_dist=1e20;
					for(int j=0;j<3;j++) {
						Vector3 c;
						Vector3 inters;
						Geometry::get_closest_points_between_segments(p_vtx[j],p_vtx[(j+1)%3],ray_from,ray_to,inters,c);
						float d=c.distance_to(intersection);
						if (j==0 || d<closest_dist) {
							closest_dist=d;
							intersection=inters;
						}
					}
				}

				Vector2 uv = get_uv(intersection,p_vtx,p_uv);


				int uv_x = CLAMP(Math::fposmod(uv.x,1.0)*bake_texture_size,0,bake_texture_size-1);
				int uv_y = CLAMP(Math::fposmod(uv.y,1.0)*bake_texture_size,0,bake_texture_size-1);

				int ofs = uv_y*bake_texture_size+uv_x;
				albedo_accum.r+=p_material.albedo[ofs].r;
				albedo_accum.g+=p_material.albedo[ofs].g;
				albedo_accum.b+=p_material.albedo[ofs].b;
				albedo_accum.a+=p_material.albedo[ofs].a;

				emission_accum.r+=p_material.emission[ofs].r;
				emission_accum.g+=p_material.emission[ofs].g;
				emission_accum.b+=p_material.emission[ofs].b;

				normal_accum+=normal;

				alpha+=1.0;

			}
		}


		if (alpha==0) {
			//could not in any way get texture information.. so use closest point to center

			Face3 f( p_vtx[0],p_vtx[1],p_vtx[2]);
			Vector3 inters = f.get_closest_point_to(p_aabb.pos+p_aabb.size*0.5);

			Vector2 uv = get_uv(inters,p_vtx,p_uv);

			int uv_x = CLAMP(Math::fposmod(uv.x,1.0)*bake_texture_size,0,bake_texture_size-1);
			int uv_y = CLAMP(Math::fposmod(uv.y,1.0)*bake_texture_size,0,bake_texture_size-1);

			int ofs = uv_y*bake_texture_size+uv_x;

			alpha = 1.0/(color_scan_cell_width*color_scan_cell_width);

			albedo_accum.r=p_material.albedo[ofs].r*alpha;
			albedo_accum.g=p_material.albedo[ofs].g*alpha;
			albedo_accum.b=p_material.albedo[ofs].b*alpha;
			albedo_accum.a=p_material.albedo[ofs].a*alpha;

			emission_accum.r=p_material.emission[ofs].r*alpha;
			emission_accum.g=p_material.emission[ofs].g*alpha;
			emission_accum.b=p_material.emission[ofs].b*alpha;

			normal_accum*=alpha;


		} else {

			float accdiv = 1.0/(color_scan_cell_width*color_scan_cell_width);
			alpha*=accdiv;

			albedo_accum.r*=accdiv;
			albedo_accum.g*=accdiv;
			albedo_accum.b*=accdiv;
			albedo_accum.a*=accdiv;

			emission_accum.r*=accdiv;
			emission_accum.g*=accdiv;
			emission_accum.b*=accdiv;

			normal_accum*=accdiv;

		}

		//put this temporarily here, corrected in a later step
		p_baker->bake_cells[p_idx].albedo[0]+=albedo_accum.r;
		p_baker->bake_cells[p_idx].albedo[1]+=albedo_accum.g;
		p_baker->bake_cells[p_idx].albedo[2]+=albedo_accum.b;
		p_baker->bake_cells[p_idx].emission[0]+=emission_accum.r;
		p_baker->bake_cells[p_idx].emission[1]+=emission_accum.g;
		p_baker->bake_cells[p_idx].emission[2]+=emission_accum.b;
		p_baker->bake_cells[p_idx].normal[0]+=normal_accum.x;
		p_baker->bake_cells[p_idx].normal[1]+=normal_accum.y;
		p_baker->bake_cells[p_idx].normal[2]+=normal_accum.z;
		p_baker->bake_cells[p_idx].alpha+=alpha;

		static const Vector3 side_normals[6]={
			Vector3(-1, 0, 0),
			Vector3( 1, 0, 0),
			Vector3( 0,-1, 0),
			Vector3( 0, 1, 0),
			Vector3( 0, 0,-1),
			Vector3( 0, 0, 1),
		};

		/*
		for(int i=0;i<6;i++) {
			if (normal.dot(side_normals[i])>CMP_EPSILON) {
				p_baker->bake_cells[p_idx].used_sides|=(1<<i);
			}
		}*/


	} else {
		//go down

		int half = (1<<(p_baker->cell_subdiv-1)) >> (p_level+1);
		for(int i=0;i<8;i++) {

			Rect3 aabb=p_aabb;
			aabb.size*=0.5;

			int nx=p_x;
			int ny=p_y;
			int nz=p_z;

			if (i&1) {
				aabb.pos.x+=aabb.size.x;
				nx+=half;
			}
			if (i&2) {
				aabb.pos.y+=aabb.size.y;
				ny+=half;
			}
			if (i&4) {
				aabb.pos.z+=aabb.size.z;
				nz+=half;
			}
			//make sure to not plot beyond limits
			if (nx<0 || nx>=p_baker->axis_cell_size[0] || ny<0 || ny>=p_baker->axis_cell_size[1] || nz<0 || nz>=p_baker->axis_cell_size[2])
				continue;

			{
				Rect3 test_aabb=aabb;
				//test_aabb.grow_by(test_aabb.get_longest_axis_size()*0.05); //grow a bit to avoid numerical error in real-time
				Vector3 qsize = test_aabb.size*0.5; //quarter size, for fast aabb test

				if (!fast_tri_box_overlap(test_aabb.pos+qsize,qsize,p_vtx)) {
				//if (!Face3(p_vtx[0],p_vtx[1],p_vtx[2]).intersects_aabb2(aabb)) {
					//does not fit in child, go on
					continue;
				}

			}

			if (p_baker->bake_cells[p_idx].childs[i]==Baker::CHILD_EMPTY) {
				//sub cell must be created

				uint32_t child_idx = p_baker->bake_cells.size();
				p_baker->bake_cells[p_idx].childs[i]=child_idx;
				p_baker->bake_cells.resize( p_baker->bake_cells.size() + 1);
				p_baker->bake_cells[child_idx].level=p_level+1;

			}


			_plot_face(p_baker->bake_cells[p_idx].childs[i],p_level+1,nx,ny,nz,p_vtx,p_uv,p_material,aabb,p_baker);
		}
	}
}
	//---------------------------------------------------------------------
	void RenderSystem::addClipPlane (Real A, Real B, Real C, Real D)
	{
		addClipPlane(Plane(A, B, C, D));
	}
Exemple #19
0
// on "init" you need to initialize your instance
bool City_layer::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !Layer::init() )
    {
        return false;
    }
    selected=nullptr;
    horizontalPlane=Plane(Vec3(0,1,0),Vec3(0,0,0));
    _rotation=0.f;
    //_firstrotation=0.f;
    
    Size size=Director::getInstance()->getWinSize();
    pCamera=Camera::createPerspective(60.0,size.width/size.height,0.1f,2000);
    pCamera->setCameraFlag(CameraFlag::USER1);
    pCamera->setPosition3D(Vec3(0,250,500));
    pCamera->lookAt(Vec3(0,0,0));
    addChild(pCamera);
    //sdsdsdsd
    
        node1=DrawNode3D::create();
        node1->clear();
        node1->setCameraMask(2);
        addChild(node1);
    
   // 天空盒
//    Skybox*sky=Skybox::create("Default/desert_left.jpg", "Default/desert_right.jpg", "Default/desert_top.jpg", "Default/desert_top.jpg", "Default/desert_front.jpg", "Default/desert_back.jpg");
//    sky->setCameraMask(2);
//    addChild(sky);

    
    
//    Terrain::DetailMap r("TerrainTest/dirt.jpg"),g("TerrainTest/Grass2.jpg"),b("TerrainTest/road.jpg"),a("TerrainTest/GreenSkin.jpg");
//    
//    Terrain::TerrainData data("TerrainTest/heightmap16.jpg","TerrainTest/alphamap.png",r,g,b,a);
//    
//    _terrain = Terrain::create(data,Terrain::CrackFixedType::SKIRT);
//    _terrain->setLODDistance(3.2f,6.4f,9.6f);
//    _terrain->setMaxDetailMapAmount(4);
//    addChild(_terrain);
//    _terrain->setCameraMask(2);
//    _terrain->setDrawWire(false);
    
    
    Terrain::DetailMap r("TerrainTest/dirt.jpg"),g("TerrainTest/Grass2.jpg"),b("TerrainTest/road.jpg"),a("TerrainTest/GreenSkin.jpg");
    
    //Terrain::TerrainData data("TerrainTest/heightmap0.jpg","TerrainTest/alphamapyellow.png",r,g,b,a);
   
    Terrain::TerrainData data("TerrainTest/heightmap16.jpg","TerrainTest/alphamap.png",r,g,b,a);
   
    _terrain = Terrain::create(data,Terrain::CrackFixedType::SKIRT);
    //_terrain->setLightMap("TerrainTest/Lightmap.png");
  
    _terrain->setLODDistance(3.2f,6.4f,9.6f);
    _terrain->setMaxDetailMapAmount(4);
    addChild(_terrain);
   
    _terrain->setScale(20.f, 1.f);
    _terrain->setScaleZ(20.f);
    _terrain->setCameraMask(2);
    _terrain->setDrawWire(false);

    // create_house("garbageTruck", Vec3(-50,0,100), Vec3(0,0,0),0.3);
    create_house("fanceWooden", Vec3(100,0,-100), Vec3(0,0,0),0.3);
    
    create_human1(Vec3(-50,0,100),1);
    create_human2(Vec3(50,0,100),1);
    
    create_house("houseBig", Vec3(-100,0,-100), Vec3(0,0,0),0.3);
    
//    auto floor=Sprite3D::create("plane.c3t","plane.png");
//    floor->setPosition3D(Vec3(480,0,0));
//    floor->setScaleX(100);
//    floor->setScaleY(100);
//    floor->setRotation3D(Vec3(90,0,0));
//    floor->setCameraMask(2);
//    addChild(floor);
//    
//    
//    Charecter1*player=Charecter1::create();
//    player->setPosition3D(Vec3(480,10,0));
//    player->setRotation3D(Vec3(0,0,0));
//    player->stand();
//    player->setCameraMask(2);
//    addChild(player,0,9);
//    
//    create_monster(Vec3(300,10,200));
//    create_monster(Vec3(500,10,-100));
//    create_monster(Vec3(-100,10,-400));
//    create_monster(Vec3(-100,10,300));
//    create_monster(Vec3(-900,10,1300));
//    create_monster(Vec3(-900,10,-1300));
//     create_monster(Vec3(1500,10,1300));
//     create_monster(Vec3(1500,10,-1300));
    auto touchEvt=EventListenerTouchOneByOne::create();
    touchEvt->onTouchBegan=[=](Touch*ptouch,Event*pevent){
        
        
            auto location = ptouch->getLocationInView();
            auto obbSize = vecObj.size();
            if(obbSize)
            {
                CCLOG("size:%lu",obbSize);
                Ray ray;
                calculateRayByLocationInView(&ray,location);
                bool touchOne=false;
                for(decltype(obbSize) i = 0; i < obbSize; i++)
                {
//                    Vec3 des = ray.intersects(horizontalPlane);
//                    CCLOG("X:%f,Y:%f,Z:%f",des.x,des.y,des.z);
//                    CCLOG("i:%lu",i);
                    if(ray.intersects(vecObj.at(i)->getAABB()))
                    {
                        touchOne=true;
                        if(dynamic_cast<CharecterBase*>(selected)){
                            auto pp = static_cast<CharecterBase*>(selected);
                            pp->mainLogic();
                            pp->scheduleUpdate();
                            
                        }
                        selected=vecObj.at(i);
//                        Vec3 corners[8]={};
//                        AABB aabbsp1=_aabb[i];
//                        aabbsp1.getCorners(corners);
//                        node1->drawCube(corners, Color4F(1,0,0,1));

                    }
                }
            
                if(!touchOne){
                        if(selected){
                            auto location = ptouch->getLocationInView();
                            Ray ray;
                            calculateRayByLocationInView(&ray,location);
                            Vec3 des = ray.intersects(horizontalPlane);
                    
                            if(dynamic_cast<CharecterBase*>(selected)){
                                //旋转
                                selected->unscheduleAllCallbacks();
                    
                                Vec3 delta=des-selected->getPosition3D();
                    
                                float angle =  Vec2(0,1).getAngle(Vec2(delta.x,delta.z));
                                if(delta.x!=0||delta.z!=0){
                                    Quaternion tt(Vec3(0,-1,0),angle);
                                    selected->setRotationQuat(tt);
                                }
                                //移动
                                auto pp = static_cast<CharecterBase*>(selected);
                                pp->speedDirection=Vec3(0,0,0);//自由移动失效
                                pp->walk();
                                
                                auto time =delta.length()/pp->walk_speed/30;
                                
                                CCLOG("%f->length,%f->time",delta.length(),time);
                                pp->runAction(Sequence::create(MoveTo::create(time, des),CallFuncN::create([=](Ref*pSender){
                                    pp->stand();
                                }),NULL));
                                
                            }else{
                                selected=nullptr;
                            }
                }
                }
            }
        

        
        return true;
    };
    touchEvt->onTouchMoved=[=](Touch*ptouch,Event*pevent){
           // 圆面相机 第3人称相机的移动
//            auto location=ptouch->getLocation();
//            Vec2 newPos=ptouch->getPreviousLocation()-location;
//            _rotation+=newPos.x/1000; //算出角度
//       
//            float deltax=100*sin(_rotation);//x增量
//            float deltaz=100*cos(_rotation);//z增量
//            pCamera->setPosition3D(Vec3(deltax,50,deltaz));
//            pCamera->lookAt(Vec3(0,0,0));
        auto location = ptouch->getLocation();
        auto delta=ptouch->getDelta();
        pCamera->setPosition3D(pCamera->getPosition3D()+Vec3(-delta.x,0,delta.y));
       // pCamera->lookAt(Vec3(0,0,0));
   
           };
  //    touchEvt->onTouchEnded=[=](Touch*ptouch,Event*pevent){
//    if(selected){
//        auto location = ptouch->getLocationInView();
//        Ray ray;
//        calculateRayByLocationInView(&ray,location);
//        Vec3 des = ray.intersects(horizontalPlane);
//        
//        if(dynamic_cast<CharecterBase*>(selected)){
//            //旋转
//            selected->unscheduleAllCallbacks();
//            
//            Vec3 delta=des-selected->getPosition3D();
//            
//            float angle =  Vec2(0,1).getAngle(Vec2(delta.x,delta.z));
//            if(delta.x!=0||delta.z!=0){
//                Quaternion tt(Vec3(0,-1,0),angle);
//                selected->setRotationQuat(tt);
//            }
//            //移动
//            auto pp = static_cast<CharecterBase*>(selected);
//            pp->speedDirection=Vec3(0,0,0);//自由移动失效
//            pp->walk();
//            
//            auto time =delta.length()/pp->walk_speed/30;
//            
//            CCLOG("%f->length,%f->time",delta.length(),time);
//            pp->runAction(Sequence::create(MoveTo::create(time, des),CallFuncN::create([=](Ref*pSender){
//                pp->stand();
//            }),NULL));
//            
//        }else{
//            selected=nullptr;
//        }
//        
//    }
     // };

    
    Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(touchEvt,this);
//
    scheduleUpdate();
    
    
    
    
    //地图缩放
    auto listener=EventListenerTouchAllAtOnce::create();
    listener->onTouchesBegan=[&](const std::vector<Touch*>&touches,Event *pevent)
    {
        Director*director=Director::getInstance();
        if (touches.size()>=2) {
            auto point1=director->convertToGL(touches.at(0)->getLocation());
            auto point2=director->convertToGL(touches.at(1)->getLocation());
            _distance=point1.getDistance(point2);
        }
    };
    listener->onTouchesMoved=[&](const std::vector<Touch*>&touches,Event *pevent)
    {
        
        Director*director=Director::getInstance();
        if (touches.size()>=2) {
            auto point1=director->convertToGL(touches.at(0)->getLocation());
            auto point2=director->convertToGL(touches.at(1)->getLocation());
            
            float new_distance=point1.getDistance(point2);
            float delta=new_distance-_distance;
            pCamera->setPosition3D(pCamera->getPosition3D()+Vec3(0,delta,delta));
            _distance=new_distance;
            
                   }
    };
    _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
    
    
    
    return true;
}
Exemple #20
0
void Camera::SetReflectionPlaneAttr(const Vector4& value)
{
    SetReflectionPlane(Plane(value));
}
Exemple #21
0
Variant::operator String() const {

	switch( type ) {
	
		case NIL: return ""; 
		case BOOL: return _data._bool ? "True" : "False";
		case INT: return String::num(_data._int);
		case REAL: return String::num(_data._real);
		case STRING: return *reinterpret_cast<const String*>(_data._mem);
		case VECTOR2: return operator Vector2();
		case RECT2: return operator Rect2();
		case MATRIX32: return operator Matrix32();
		case VECTOR3: return operator Vector3();
		case PLANE: return operator Plane();
		//case QUAT: 
		case _AABB: return operator AABB();
		case QUAT: return operator Quat();
		case MATRIX3: return operator Matrix3();
		case TRANSFORM: return operator Transform();
		case NODE_PATH: return operator NodePath();
		case INPUT_EVENT: return operator InputEvent();
		case COLOR: return String::num( operator Color().r)+","+String::num( operator Color().g)+","+String::num( operator Color().b)+","+String::num( operator Color().a) ;
		case DICTIONARY: {
			
			const Dictionary &d =*reinterpret_cast<const Dictionary*>(_data._mem);
			//const String *K=NULL;
			String str;
			List<Variant> keys;
			d.get_key_list(&keys);

			Vector<_VariantStrPair> pairs;

			for(List<Variant>::Element *E=keys.front();E;E=E->next()) {

				_VariantStrPair sp;
				sp.key=String(E->get());
				sp.value=d[E->get()];
				pairs.push_back(sp);
			}

			pairs.sort();

			for(int i=0;i<pairs.size();i++) {
				if (i>0)
					str+=", ";
				str+="("+pairs[i].key+":"+pairs[i].value+")";
			}
			
			return str;
		} break;
		case VECTOR3_ARRAY: { 
		
			DVector<Vector3> vec = operator DVector<Vector3>();
			String str;
			for(int i=0;i<vec.size();i++) {
			
				if (i>0)
					str+=", ";
				str=str+Variant( vec[i] );
			}
			return str;
		} break;
		case STRING_ARRAY: {

			DVector<String> vec = operator DVector<String>();
			String str;
			for(int i=0;i<vec.size();i++) {

				if (i>0)
					str+=", ";
				str=str+vec[i];
			}
			return str;
		} break;
		case INT_ARRAY: {

			DVector<int> vec = operator DVector<int>();
			String str;
			for(int i=0;i<vec.size();i++) {

				if (i>0)
					str+=", ";
				str=str+itos(vec[i]);
			}
			return str;
		} break;
		case REAL_ARRAY: {

			DVector<real_t> vec = operator DVector<real_t>();
			String str;
			for(int i=0;i<vec.size();i++) {

				if (i>0)
					str+=", ";
				str=str+rtos(vec[i]);
			}
			return str;
		} break;
		case ARRAY: {

			Array arr = operator Array();
			String str;
			for (int i=0; i<arr.size(); i++) {
				if (i)
					str+=", ";
				str += String(arr[i]);
			};
			return str;

		} break;
		case OBJECT: {

			if (_get_obj().obj)
				return "["+_get_obj().obj->get_type()+":"+itos(_get_obj().obj->get_instance_ID())+"]";
			else
				return "[Object:null]";

		} break;
		default: {
			return "["+get_type_name(type)+"]";
		}		
	}
	
	return "";
}
Exemple #22
0
void Camera::SetClipPlaneAttr(const Vector4& value)
{
    SetClipPlane(Plane(value));
}
Exemple #23
0
bool Variant::is_zero() const {

	switch( type ) {
		case NIL: {

			return true;
		} break;

		// atomic types
		case BOOL: {

			return _data._bool==false;
		} break;
		case INT: {

			return _data._int==0;

		} break;
		case REAL: {

			return _data._real==0;

		} break;
		case STRING: {

			return *reinterpret_cast<const String*>(_data._mem)==String();

		} break;

		// math types

		case VECTOR2: {

			return *reinterpret_cast<const Vector2*>(_data._mem)==Vector2();

		} break;
		case RECT2: {

			return *reinterpret_cast<const Rect2*>(_data._mem)==Rect2();

		} break;
		case MATRIX32: {

			return *_data._matrix32==Matrix32();

		} break;
		case VECTOR3: {

			return *reinterpret_cast<const Vector3*>(_data._mem)==Vector3();

		} break;
		case PLANE: {

			return *reinterpret_cast<const Plane*>(_data._mem)==Plane();

		} break;
/*
		case QUAT: {


		} break;*/
		case _AABB: {

			return *_data._aabb==AABB();
		} break;
		case QUAT: {

			*reinterpret_cast<const Quat*>(_data._mem)==Quat();

		} break;
		case MATRIX3: {

			return *_data._matrix3==Matrix3();

		} break;
		case TRANSFORM: {

			return *_data._transform == Transform();

		} break;

		// misc types
		case COLOR: {

			return *reinterpret_cast<const Color*>(_data._mem)==Color();

		} break;
		case IMAGE: {

			return _data._image->empty();

		} break;
		case _RID: {

			return *reinterpret_cast<const RID*>(_data._mem)==RID();
		} break;
		case OBJECT: {

			return _get_obj().obj==NULL;
		} break;
		case NODE_PATH: {

			return reinterpret_cast<const NodePath*>(_data._mem)->is_empty();

		} break;
		case INPUT_EVENT: {

			return _data._input_event->type==InputEvent::NONE;

		} break;
		case DICTIONARY: {

			return reinterpret_cast<const Dictionary*>(_data._mem)->empty();

		} break;
		case ARRAY: {

			return reinterpret_cast<const Array*>(_data._mem)->empty();

		} break;

		// arrays
		case RAW_ARRAY: {

			return reinterpret_cast<const DVector<uint8_t>*>(_data._mem)->size()==0;

		} break;
		case INT_ARRAY: {

			return reinterpret_cast<const DVector<int>*>(_data._mem)->size()==0;

		} break;
		case REAL_ARRAY: {

			return reinterpret_cast<const DVector<real_t>*>(_data._mem)->size()==0;

		} break;
		case STRING_ARRAY: {

			return reinterpret_cast<const DVector<String>*>(_data._mem)->size()==0;

		} break;
		case VECTOR2_ARRAY: {

			return reinterpret_cast<const DVector<Vector2>*>(_data._mem)->size()==0;

		} break;
		case VECTOR3_ARRAY: {

			return reinterpret_cast<const DVector<Vector3>*>(_data._mem)->size()==0;

		} break;
		case COLOR_ARRAY: {

			return reinterpret_cast<const DVector<Color>*>(_data._mem)->size()==0;

		} break;
		default: {}
	}

	return false;
}
void CuboidCollisionShape::GetIncidentReferencePolygon(const PhysicsObject* currentObject, const Vector3& axis, std::list<Vector3>* out_face, Vector3* out_normal, std::vector<Plane>* out_adjacent_planes) const
{
	Matrix4 wsTransform = currentObject->GetWorldSpaceTransform() * Matrix4::Scale(m_CuboidHalfDimensions);

	Matrix3 invNormalMatrix = Matrix3::Inverse(Matrix3(wsTransform));
	Matrix3 normalMatrix = Matrix3::Transpose(invNormalMatrix);
	
	Vector3 local_axis = invNormalMatrix * axis;

	int minVertex, maxVertex;
	m_CubeHull.GetMinMaxVerticesInAxis(local_axis, &minVertex, &maxVertex);

	const HullVertex& vert = m_CubeHull.GetVertex(maxVertex);

	const HullFace* best_face = 0;
	float best_correlation = -FLT_MAX;
	for (int faceIdx : vert.enclosing_faces)
	{
		const HullFace* face = &m_CubeHull.GetFace(faceIdx);
		float temp_correlation = Vector3::Dot(local_axis, face->normal);
		if (temp_correlation > best_correlation)
		{
			best_correlation = temp_correlation;
			best_face = face;
		}
	}

	if (out_normal)
	{
		*out_normal = normalMatrix * best_face->normal;
		(*out_normal).Normalise();
	}

	if (out_face)
	{
		for (int vertIdx : best_face->vert_ids)
		{
			const HullVertex& vert = m_CubeHull.GetVertex(vertIdx);
			out_face->push_back(wsTransform * vert.pos);
		}
	}

	if (out_adjacent_planes)
	{
		//Add the reference face itself to the list of adjacent planes
		Vector3 wsPointOnPlane = wsTransform * m_CubeHull.GetVertex(m_CubeHull.GetEdge(best_face->edge_ids[0]).vStart).pos;
		Vector3 planeNrml = -(normalMatrix * best_face->normal);
		planeNrml.Normalise();
		float planeDist = -Vector3::Dot(planeNrml, wsPointOnPlane);

		out_adjacent_planes->push_back(Plane(planeNrml, planeDist));
		

		for (int edgeIdx : best_face->edge_ids)
		{
			const HullEdge& edge = m_CubeHull.GetEdge(edgeIdx);

			wsPointOnPlane = wsTransform * m_CubeHull.GetVertex(edge.vStart).pos;

			for (int adjFaceIdx : edge.enclosing_faces)
			{
				if (adjFaceIdx != best_face->idx)
				{
					const HullFace& adjFace = m_CubeHull.GetFace(adjFaceIdx);

					planeNrml = -(normalMatrix * adjFace.normal);
					planeNrml.Normalise();
					planeDist = -Vector3::Dot(planeNrml, wsPointOnPlane);

					out_adjacent_planes->push_back(Plane(planeNrml, planeDist));
				}
			}	
		}
	}
}
Exemple #25
0
//=======================================================================//
void stitch::BeamTree::build(const size_t chunkSize, const uint8_t splitAxis)
{//Only makes use of cone origins to build tree. It is assumed that cones that originate next to each other points in similar directions!
    
    //New potential child trees.
    BeamTree *tree0=new BeamTree;
    BeamTree *tree1=new BeamTree;
    
    //Build the beamTree based on the end-cap centres instead of the generator centres.
    
    //=== Find centre of beam end-cap OR BV ===
    Vec3 centre;//Set to zero.
    
    if (beamSegmentVector_.size()>0)
    {
        std::vector<stitch::BeamSegment *>::const_iterator constBeamSegmentIter=beamSegmentVector_.begin();
        for (; constBeamSegmentIter!=beamSegmentVector_.end(); ++constBeamSegmentIter)
        {//Do a linear traversal through the beam segments.
            (*constBeamSegmentIter)->updateBV();
            
            if ((*constBeamSegmentIter)->hasEndCap_)
            {
                centre+=(*constBeamSegmentIter)->endCapVertices_[0];
            } else
            {
                centre+=(*constBeamSegmentIter)->getBVBrush().centre_;
            }
            
        }
        centre/=beamSegmentVector_.size();
    }
    //================================
    
    Plane binarySpacePartition(Vec3(0.0f, 0.0f, 0.0f), 0.0f);
    
    if (splitAxis==0)
    {
        binarySpacePartition=Plane(Vec3(1.0f, 0.0f, 0.0f), centre.x());//right-hand space.
    } else
        if (splitAxis==1)
        {
            binarySpacePartition=Plane(Vec3(0.0f, 1.0f, 0.0f), centre.y());//right-hand space.
        } else
            if (splitAxis==2)
            {
                binarySpacePartition=Plane(Vec3(0.0f, 0.0f, 1.0f), centre.z());//right-hand space.
            }
    
    //=== Split beam segments into two brances according to their beam orig and the binary space partition plane.
    {
        std::vector<BeamSegment *>::const_iterator beamSegmentIter=beamSegmentVector_.begin();
        for (; beamSegmentIter!=beamSegmentVector_.end(); ++beamSegmentIter)
        {
            BeamSegment *beamSegment=(*beamSegmentIter);
            
            stitch::Vec3 refVert;
            
            if (beamSegment->hasEndCap_)
            {
                refVert=beamSegment->endCapVertices_[0];
            } else
            {
                refVert=beamSegment->getBVBrush().centre_;
            }
            
            
            if (refVert*binarySpacePartition.normal_ < binarySpacePartition.d_)
            {//Object is in space of tree0.
                tree0->addBeamSegment(beamSegment);
            }
            else
            {//Object is in space of tree1.
                tree1->addBeamSegment(beamSegment);
            }
        }
        
        //beamSegmentVector_.clear();//Does not delete the beam segments pointed to by the vector entries.
        std::vector<stitch::BeamSegment *>().swap(beamSegmentVector_);//swap with new empty vector.
    }
    //===
    
    
    //=== Add child trees to this parent and build the child hierarchy ===
    {
        if (tree0->beamSegmentVector_.size()>0)
        {
            beamTreeVector_.push_back(tree0);//Add child tree. There can be more than two child trees if the build mehod is called multiple times.
        }
        if (tree0->beamSegmentVector_.size()>chunkSize)
        {
            tree0->build(chunkSize, (splitAxis+1)%3);//Recursively build the tree.
        }
        
        if (tree1->beamSegmentVector_.size()>0)
        {
            beamTreeVector_.push_back(tree1);//Add child tree. There can be more than two child trees if the build mehod is called multiple times.
        }
        if (tree1->beamSegmentVector_.size()>chunkSize)
        {
            tree1->build(chunkSize, (splitAxis+1)%3);//Recursively build the tree.
        }
    }
    //====================================================================
}
Exemple #26
0
void PlaneReflection::setHeight (float height)
{
    mWaterPlane = Plane(Ogre::Vector3(0,0,1), height);
    mErrorPlane = Plane(Ogre::Vector3(0,0,1), height - 5);
    mErrorPlaneUnderwater = Plane(Ogre::Vector3(0,0,-1), -height - 5);
}
Exemple #27
0
Vector<Plane> CameraMatrix::get_projection_planes(const Transform& p_transform) const {

	/** Fast Plane Extraction from combined modelview/projection matrices.
	 * References:
	 * http://www.markmorley.com/opengl/frustumculling.html
	 * http://www2.ravensoft.com/users/ggribb/plane%20extraction.pdf
	 */

	Vector<Plane> planes;

	const float * matrix = (const float*)this->matrix;

	Plane new_plane;

	///////--- Near Plane ---///////
	new_plane=Plane(matrix[ 3] + matrix[ 2],
		      matrix[ 7] + matrix[ 6],
		      matrix[11] + matrix[10],
		      matrix[15] + matrix[14]);

	new_plane.normal=-new_plane.normal;
	new_plane.normalize();

	planes.push_back( p_transform.xform(new_plane) );

	///////--- Far Plane ---///////
	new_plane=Plane(matrix[ 3] - matrix[ 2],
		      matrix[ 7] - matrix[ 6],
		      matrix[11] - matrix[10],
		      matrix[15] - matrix[14]);

	new_plane.normal=-new_plane.normal;
	new_plane.normalize();

	planes.push_back( p_transform.xform(new_plane) );


	///////--- Left Plane ---///////
	new_plane=Plane(matrix[ 3] + matrix[ 0],
		      matrix[ 7] + matrix[ 4],
		      matrix[11] + matrix[ 8],
		      matrix[15] + matrix[12]);

	new_plane.normal=-new_plane.normal;
	new_plane.normalize();

	planes.push_back( p_transform.xform(new_plane) );


	///////--- Top Plane ---///////
	new_plane=Plane(matrix[ 3] - matrix[ 1],
		      matrix[ 7] - matrix[ 5],
		      matrix[11] - matrix[ 9],
		      matrix[15] - matrix[13]);


	new_plane.normal=-new_plane.normal;
	new_plane.normalize();

	planes.push_back( p_transform.xform(new_plane) );


	///////--- Right Plane ---///////
	new_plane=Plane(matrix[ 3] - matrix[ 0],
		      matrix[ 7] - matrix[ 4],
		      matrix[11] - matrix[ 8],
		      matrix[15] - matrix[12]);


	new_plane.normal=-new_plane.normal;
	new_plane.normalize();

	planes.push_back( p_transform.xform(new_plane) );


	///////--- Bottom Plane ---///////
	new_plane=Plane(matrix[ 3] + matrix[ 1],
		      matrix[ 7] + matrix[ 5],
		      matrix[11] + matrix[ 9],
		      matrix[15] + matrix[13]);


	new_plane.normal=-new_plane.normal;
	new_plane.normalize();

	planes.push_back( p_transform.xform(new_plane) );

	return planes;
}
Exemple #28
0
Water::Water (Ogre::Camera *camera, RenderingManager* rend) :
    mCamera (camera), mSceneMgr (camera->getSceneManager()),
    mIsUnderwater(false), mVisibilityFlags(0),
    mActive(1), mToggled(1),
    mRendering(rend),
    mWaterTimer(0.f),
    mReflection(NULL),
    mRefraction(NULL),
    mSimulation(NULL),
    mPlayer(0,0)
{
    mSimulation = new RippleSimulation(mSceneMgr);

    mSky = rend->getSkyManager();

    mMaterial = MaterialManager::getSingleton().getByName("Water");

    mTop = 0;

    mIsUnderwater = false;

    mWaterPlane = Plane(Vector3::UNIT_Z, 0);

    MeshManager::getSingleton().createPlane("water", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,  mWaterPlane, CELL_SIZE*5, CELL_SIZE * 5, 10, 10, true, 1, 3,3, Vector3::UNIT_Y);

    mWater = mSceneMgr->createEntity("water");
    mWater->setVisibilityFlags(RV_Water);
    mWater->setCastShadows(false);
    mWater->setRenderQueueGroup(RQG_Alpha);

    mWaterNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();

    mWaterNode->attachObject(mWater);

    applyRTT();
    applyVisibilityMask();

    mWater->setMaterial(mMaterial);

    setHeight(mTop);

    sh::MaterialInstance* m = sh::Factory::getInstance ().getMaterialInstance ("Water");
    m->setListener (this);

    // ----------------------------------------------------------------------------------------------
    // ---------------------------------- reflection debug overlay ----------------------------------
    // ----------------------------------------------------------------------------------------------
/*
    if (Settings::Manager::getBool("shader", "Water"))
    {
        OverlayManager& mgr = OverlayManager::getSingleton();
        Overlay* overlay;
        // destroy if already exists
        if ((overlay = mgr.getByName("ReflectionDebugOverlay")))
            mgr.destroy(overlay);

        overlay = mgr.create("ReflectionDebugOverlay");

        if (MaterialManager::getSingleton().resourceExists("Ogre/ReflectionDebugTexture"))
            MaterialManager::getSingleton().remove("Ogre/ReflectionDebugTexture");
        MaterialPtr debugMat = MaterialManager::getSingleton().create(
            "Ogre/ReflectionDebugTexture",
            ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);

        debugMat->getTechnique(0)->getPass(0)->setLightingEnabled(false);
        debugMat->getTechnique(0)->getPass(0)->createTextureUnitState(mReflectionTexture->getName());

        OverlayContainer* debugPanel;

        // destroy container if exists
        try
        {
            if ((debugPanel =
                static_cast<OverlayContainer*>(
                    mgr.getOverlayElement("Ogre/ReflectionDebugTexPanel"
                ))))
                mgr.destroyOverlayElement(debugPanel);
        }
        catch (Ogre::Exception&) {}

        debugPanel = (OverlayContainer*)
            (OverlayManager::getSingleton().createOverlayElement("Panel", "Ogre/ReflectionDebugTexPanel"));
        debugPanel->_setPosition(0, 0.55);
        debugPanel->_setDimensions(0.3, 0.3);
        debugPanel->setMaterialName(debugMat->getName());
        debugPanel->show();
        overlay->add2D(debugPanel);
        overlay->show();
    }
*/
}
Exemple #29
0
// The resulting hull will not contain interior points
// Note that this is a cheap and cheerful implementation that can only handle
// reasonably small point sets. However, except for the final hull it doesn't do any dynamic
// memory allocation - all the work happens on the stack.
Hull* Hull::MakeHull(int numPoints, const Point3* pPoints)
{
	assert(numPoints >= 4);
	assert(pPoints);

	// check first 4 points are disjoint
	// TODO: make it search points so it can cope better with this
	assert(Length(pPoints[1] - pPoints[0]) > 0.01f);
	assert(Length(pPoints[2] - pPoints[0]) > 0.01f);
	assert(Length(pPoints[3] - pPoints[0]) > 0.01f);
	assert(Length(pPoints[2] - pPoints[1]) > 0.01f);
	assert(Length(pPoints[3] - pPoints[1]) > 0.01f);
	assert(Length(pPoints[3] - pPoints[2]) > 0.01f);

	s_pPoints = pPoints;

	// put all temp faces on a free list
	TmpFace tmpFaces[kMaxFaces];

	s_firstFreeTmpFace = 0;
	s_firstUsedTmpFace = -1;
	s_pTmpFaces = tmpFaces;

	for (short i = 0; i < kMaxEdges; i++)
	{
		tmpFaces[i].m_index = i;
		tmpFaces[i].m_next = i + 1;
	}
	tmpFaces[kMaxFaces - 1].m_next = -1;

	// put all temp edges on a free list
	TmpEdge tmpEdges[kMaxEdges];

	s_firstFreeTmpEdge = 0;
	s_firstUsedTmpEdge = -1;
	s_pTmpEdges = tmpEdges;

	for (short i = 0; i < kMaxEdges; i++)
	{
		tmpEdges[i].m_index = i;
		tmpEdges[i].m_next = i + 1;
	}
	tmpEdges[kMaxEdges - 1].m_next = -1;

	// make initial tetrahedron
	Plane plane = Plane(pPoints[0], pPoints[1], pPoints[2]);

	Scalar dot = Dot(plane, pPoints[3]);
	assert(Abs(dot) > 0.01f);			// first 4 points are co-planar

	if (IsNegative(dot))
	{
		AddTmpFace(0, 1, 2);
		AddTmpFace(1, 0, 3);
		AddTmpFace(0, 2, 3);
		AddTmpFace(2, 1, 3);
	}
	else
	{
		AddTmpFace(2, 1, (short)0);
		AddTmpFace(1, 2, 3);
		AddTmpFace(2, 0, 3);
		AddTmpFace(0, 1, 3);
	}

	// merge all remaining points
	for (int i = 4; i < numPoints; i++)
		if (RemoveVisibleFaces(pPoints[i]) > 0)
			FillHole(i);

	return MakeHullFromTemp();
}
void PlayState::update(Real delta)
{
	// fps cam update
	Vector3 moveVect = mCam->mCamera->getAbsoluteDirection()*7*delta*
		(mInput->isKeyDown("KC_W")-mInput->isKeyDown("KC_S"))
		+mCam->mCamera->getAbsoluteRight()*7*delta*
		(mInput->isKeyDown("KC_D")-mInput->isKeyDown("KC_A"));

	Real len = moveVect.normalize();

	// hacky raycast for portals
	RaycastReport r = mPhysics->raycast(mCam->getPosition(),moveVect,
		len,0,COLLISION_GROUP_2);//COLLISION_GROUP_2, COLLISION_GROUP_2);

	if(!r.hit)
	{
		mCam->mPosNode->setPosition(mCam->mPosNode->getPosition()
			+ moveVect * len);
	}
	else
	{
		// must be a portal
		Portal* p = static_cast<Portal*>(r.userData);

		// hacky and not so smooth portal transition
		if(r.normal.angleBetween(p->mDirection) < 30.f)
		{
			Real distTravelled = r.position.distance(mCam->getPosition());
			
			mCam->mPosNode->setPosition(p->mNode->localToWorldPosition(
				p->mMesh->worldToLocalPosition(mCam->getPosition())));
			mCam->mOriNode->setOrientation(p->mNode->localToWorldOrientation(
				p->mMesh->worldToLocalOrientation(mCam->mOriNode->getOrientation())));
			
			len -= 2*distTravelled;

			Vector3 newDir = mCam->getDirection();
			mCam->mPosNode->setPosition(mCam->mPosNode->getPosition()
				+ newDir * len);

			//mCam->up1 = p->upv;
			//mCam->up2 = p->mSibling->upv;
			//mCam->slerpTime = 1.f;
		}
		else
		{
			mCam->mPosNode->setPosition(mCam->mPosNode->getPosition()
				+ moveVect * len);
		}
	}

	// update player position with the chunk generator
	mGen->setPlayerPos(mCam->getPosition());
	
	// same o' same o'
	if(mInput->wasKeyPressed("KC_ESCAPE"))
		mEngine->shutdown();

	// screenshots
	if(mInput->wasKeyPressed("KC_P"))
		mGfx->takeScreenshot(TimeManager::getPtr()->getTimestamp());

	// update debug overlay
	mFpsText->setCaption("FPS: "+ StringUtils::toString(1.f/delta));
	mBatchCountText->setCaption("Batches: " 
		+ StringUtils::toString(mGfx->getBatchCount()));
	mActiveChunkCountText->setCaption("Active Chunks: " +
		StringUtils::toString(mGen->getNumActiveChunks()));
	mGeneratedChunkCountText->setCaption("Generated Chunks: " +
		StringUtils::toString(mGen->getNumGeneratedChunks()));

	if(mInput->wasButtonPressed("MB_Right"))
	{
		if(mInput->isKeyDown("KC_L"))
		{
			RaycastReport r = mPhysics->raycast(mCam->getPosition(),mCam->getDirection(),
				50.f,COLLISION_GROUP_3,COLLISION_GROUP_3);

			if(r.hit && r.userData)
			{
				BasicChunk* bc = static_cast<BasicChunk*>(r.userData);
				ChunkCoords cc = getBlockFromRaycast(r.position, 
					r.normal, bc, true);

				for(int i = -1; i <= 1; ++i)
					for(int j = -1; j <= 1; ++j)
						for(int k = -1; k <= 1; ++k)
				{
					ChunkCoords cc2 = cc + ChunkCoords(i,j,k);
					BasicChunk* bc2 = correctChunkCoords(bc, cc2);
					cc2.data = 0;
					bc2->changeBlock(cc2);
				}
			}
		}
		else if(!mInput->isKeyDown("KC_LSHIFT"))
		{
			RaycastReport r = mPhysics->raycast(mCam->getPosition(),mCam->getDirection(),
				8.f,COLLISION_GROUP_3,COLLISION_GROUP_3);

			if(r.hit && r.userData)
			{
				BasicChunk* bc = static_cast<BasicChunk*>(r.userData);
				ChunkCoords cc = getBlockFromRaycast(r.position, 
					r.normal, bc, true);
				bc = correctChunkCoords(bc, cc);
				cc.data = 0;
				bc->changeBlock(cc);
			}
		}
		else
		{
			RaycastReport r = mPhysics->raycast(mCam->getPosition(),mCam->getDirection(),
				50.f,COLLISION_GROUP_3,COLLISION_GROUP_3);

			// YUCK
			if(r.hit && r.userData)
			{
				BasicChunk* bc = static_cast<BasicChunk*>(r.userData);
				ChunkCoords cc = getBlockFromRaycast(r.position, r.normal, bc, false);

				bc = correctChunkCoords(bc, cc);

				BlockDirection d = getBlockDirectionFromVector(r.normal);
				BlockDirection d_ = getBlockDirectionFromVector(r.normal * -1);
				BlockDirection up = getBlockDirectionFromVector(
					Plane(r.normal, 0).projectVector(mCam->mCamera->getAbsoluteUp()));

				ChunkCoords cc2 = cc << up;
				BasicChunk* bc2 = correctChunkCoords(bc, cc2);

				if(!getBlockVal(bc, cc) && !getBlockVal(bc2, cc2) 
					&& getBlockVal(bc, cc << d_) && getBlockVal(bc2, cc2 << d_))
				{
					Vector3 adjPos = bc->getPosition() - OFFSET + Vector3(cc.x, cc.y, cc.z);
					adjPos -= BLOCK_NORMALS[d] * 0.5f;
					adjPos += BLOCK_NORMALS[up] * 0.5f;

					for(int i = 0; i < 2; ++i)
					{
						if(mPortals[1]->chunks[0])
							mPortals[1]->chunks[0]->clearLights();
					}

					mPortals[1]->lightVals[0] = getLightVal(bc, cc);
					mPortals[1]->lightVals[1] = getLightVal(bc2, cc2);

					mPortals[1]->cc[0] = cc;
					mPortals[1]->cc[1] = cc2;

					mPortals[1]->chunks[0] = bc;

					if(bc2 != bc)
					{
						mPortals[1]->chunks[1] = bc2;
					}
					else
					{
						mPortals[1]->chunks[1] = 0;
					}

					mPortals[1]->placed = true;

					if(mPortals[0]->placed && mPortals[1]->placed)
					{
						for(int i = 0; i < 2; ++i)
						{
							if(mPortals[0]->lightVals[i] < mPortals[1]->lightVals[i])
							{
								BasicChunk* tmp = mPortals[0]->chunks[i] ? mPortals[0]->chunks[i] : 
									mPortals[0]->chunks[0];
								tmp->addLight(mPortals[0]->cc[i], mPortals[1]->lightVals[i]);
							}
							else
							{
								BasicChunk* tmp = mPortals[1]->chunks[i] ? mPortals[1]->chunks[i] : 
									mPortals[1]->chunks[0];
								tmp->addLight(mPortals[1]->cc[i], mPortals[0]->lightVals[i]);
							}
						}
					}

					mPortals[1]->setPosition(adjPos);
					mPortals[1]->setDirection(d, up);
				}
			}
		}
	}

	if(mInput->wasButtonPressed("MB_Left"))
	{
		if(!mInput->isKeyDown("KC_LSHIFT"))
		{
			RaycastReport r = mPhysics->raycast(mCam->getPosition(),mCam->getDirection(),
				5.f,COLLISION_GROUP_3,COLLISION_GROUP_3);

			if(r.hit && r.userData)
			{
				BasicChunk* bc = static_cast<BasicChunk*>(r.userData);
				ChunkCoords cc = getBlockFromRaycast(r.position, r.normal, bc, false);
				bc = correctChunkCoords(bc, cc);
				cc.data = mBlockSelected;
				bc->changeBlock(cc);
			}
		}
		else
		{
			RaycastReport r = mPhysics->raycast(mCam->getPosition(),mCam->getDirection(),
				50.f,COLLISION_GROUP_3,COLLISION_GROUP_3);

			// YUCK
			if(r.hit && r.userData)
			{
				BasicChunk* bc = static_cast<BasicChunk*>(r.userData);
				ChunkCoords cc = getBlockFromRaycast(r.position, r.normal, bc, false);

				bc = correctChunkCoords(bc, cc);

				BlockDirection d = getBlockDirectionFromVector(r.normal);
				BlockDirection d_ = getBlockDirectionFromVector(r.normal * -1);
				BlockDirection up = getBlockDirectionFromVector(
					Plane(r.normal, 0).projectVector(mCam->mCamera->getAbsoluteUp()));

				ChunkCoords cc2 = cc << up;
				BasicChunk* bc2 = correctChunkCoords(bc, cc2);

				if(!getBlockVal(bc, cc) && !getBlockVal(bc2, cc2) 
					&& getBlockVal(bc, cc << d_) && getBlockVal(bc2, cc2 << d_))
				{
					Vector3 adjPos = bc->getPosition() - OFFSET + Vector3(cc.x, cc.y, cc.z);
					adjPos -= BLOCK_NORMALS[d] * 0.5f;
					adjPos += BLOCK_NORMALS[up] * 0.5f;

					for(int i = 0; i < 2; ++i)
					{
						if(mPortals[0]->chunks[0])
							mPortals[0]->chunks[0]->clearLights();
					}

					mPortals[0]->lightVals[0] = getLightVal(bc, cc);
					mPortals[0]->lightVals[1] = getLightVal(bc2, cc2);

					mPortals[0]->cc[0] = cc;
					mPortals[0]->cc[1] = cc2;

					mPortals[0]->chunks[0] = bc;

					if(bc2 != bc)
					{
						mPortals[0]->chunks[1] = bc2;

					}
					else
					{
						mPortals[0]->chunks[1] = 0;
					}

					mPortals[0]->placed = true;

					if(mPortals[0]->placed && mPortals[1]->placed)
					{
						for(int i = 0; i < 2; ++i)
						{
							if(mPortals[0]->lightVals[i] < mPortals[1]->lightVals[i])
							{
								BasicChunk* tmp = mPortals[0]->chunks[i] ? mPortals[0]->chunks[i] : 
									mPortals[0]->chunks[0];
								tmp->addLight(mPortals[0]->cc[i], mPortals[1]->lightVals[i]);
							}
							else
							{
								BasicChunk* tmp = mPortals[1]->chunks[i] ? mPortals[1]->chunks[i] : 
									mPortals[1]->chunks[0];
								tmp->addLight(mPortals[1]->cc[i], mPortals[0]->lightVals[i]);
							}
						}
					}

					mPortals[0]->setPosition(adjPos);
					mPortals[0]->setDirection(d, up);
				}
			}
		}
	}
}