//-----------------------------------------------------------------------------
	void ZonePlugin::zoneUtility( void )
	{
		const osScalar drawExtent = _zoneExtent.x * OS_SCALAR( 2.0 ) - 0.005f;
		if( 1 == _solid )
		{
			// colors for checkerboard
			const Color gray(0.27f);
			Color zoneGray( getZoneColor() );
			zoneGray.setR( zoneGray.r() * gray.r() );
			zoneGray.setG( zoneGray.g() * gray.g() );
			zoneGray.setB( zoneGray.b() * gray.b() );
			// draw checkerboard grid
			drawXZCheckerboardGrid( drawExtent, 10, position(), zoneGray, gray);
#if 0
			AABBox kZoneAABBox;
			kZoneAABBox.initializeWithCenterAndExtent( position(), _zoneExtent );
			kZoneAABBox.draw( getZoneColor() );
#endif
		}
		else
		{
			// alternate style
			drawXZLineGrid( drawExtent, 1, position(), _ZoneColor );
		}

		const osScalar borderWidth = getBorderWidth();
		if( borderWidth > 0 )
		{
			drawXZLineGrid( drawExtent + borderWidth * OS_SCALAR( 2.0 ), 1, position(), _BorderColor );
		}
	}
Beispiel #2
0
	/**
	* @return True if the bounding box collides or is inside this frustum
	*/
	template<class T> bool Frustum<T>::collideWithAABBox(const AABBox<T> &bbox) const
	{
		for (auto &plane : planes)
		{
			const Vector3<T> &normal = plane.getNormal();

			Point3<T> nVertex(bbox.getMax());
			if(normal.X >= 0.0)
			{
				nVertex.X = bbox.getMin().X;
			}
			if(normal.Y >= 0.0)
			{
				nVertex.Y = bbox.getMin().Y;
			}
			if(normal.Z >= 0.0)
			{
				nVertex.Z = bbox.getMin().Z;
			}

			if (plane.distance(nVertex) > 0.0)
			{
				return false;
			}
		}

		return true;
	}
	/**
	 * Split the bounding box in several bounding boxes at limitSize.
	 * If original box doesn't exceed limit size, the original box is returned.
	 */
	std::vector<AABBox<float>> SplitBoundingBox::split(const AABBox<float> &aabbox) const
	{
		std::vector<float> axisSplits[3];
		for(unsigned int axis=0; axis<3; ++axis)
		{
			float size = aabbox.getHalfSize(axis) * 2.0f;
			axisSplits[axis].push_back(aabbox.getMin()[axis]);

			auto nbSplits = static_cast<int>(std::ceil(size/limitSize));
			float maxValue = aabbox.getMax()[axis];

			for(int split = 0; split < nbSplits; ++split)
			{
				float splitValue = std::min(aabbox.getMin()[axis] + limitSize*(split+1), maxValue);
				axisSplits[axis].push_back(splitValue);
			}
		}

		std::vector<AABBox<float>> splittedBoundingBox;
		for(unsigned int x=1; x<axisSplits[0].size(); ++x)
		{
			for(unsigned int y=1; y<axisSplits[1].size(); ++y)
			{
				for(unsigned int z=1; z<axisSplits[2].size(); ++z)
				{
					Point3<float> minPoint(axisSplits[0][x-1], axisSplits[1][y-1], axisSplits[2][z-1]);
					Point3<float> maxPoint(axisSplits[0][x], axisSplits[1][y], axisSplits[2][z]);

					splittedBoundingBox.emplace_back(AABBox<float>(minPoint, maxPoint));
				}
			}
		}

		return splittedBoundingBox;
	}
Beispiel #4
0
	void SunLightSource::UpdateSMCamera(Camera const & scene_camera)
	{
		float3 const dir = this->Direction();

		float3 up_vec;
		if (abs(MathLib::dot(-dir, scene_camera.UpVec())) > 0.95f)
		{
			up_vec = scene_camera.RightVec();
		}
		else
		{
			up_vec = scene_camera.UpVec();
		}

		float4x4 light_view = MathLib::look_at_lh(-dir, float3(0, 0, 0), up_vec);

		AABBox const aabb = CalcFrustumExtents(scene_camera, scene_camera.NearPlane(), scene_camera.FarPlane(), light_view);

		float3 const & center = aabb.Center();
		float3 view_pos = MathLib::transform_coord(float3(center.x(), center.y(), aabb.Min().z()), MathLib::inverse(light_view));
		sm_camera_->ViewParams(view_pos, view_pos + dir, up_vec);

		float3 dimensions = aabb.Max() - aabb.Min();
		sm_camera_->ProjOrthoParams(dimensions.x(), dimensions.y(), 0.0f, dimensions.z());
	}
	bool FrustumShadowData::areIdenticalAABBox(const AABBox<float> &shadowCasterReceiverBox1, const AABBox<float> &shadowCasterReceiverBox2) const
	{
		constexpr float SQUARE_EPSILON = 0.0001f * 0.0001f;

		return shadowCasterReceiverBox1.getMin().squareDistance(shadowCasterReceiverBox2.getMin())<SQUARE_EPSILON
				&& shadowCasterReceiverBox1.getMax().squareDistance(shadowCasterReceiverBox2.getMax())<SQUARE_EPSILON;
	}
	bool ZonePlugin::isVehicleInsideBorder( const AbstractVehicle& vehicle ) const
	{
		osVector3 checkZoneExtent = _zoneExtent;
		checkZoneExtent.x += _borderWidth;	
		checkZoneExtent.z += _borderWidth;
		AABBox testBox;
		testBox.initializeWithCenterAndExtent( position(), checkZoneExtent );
		return testBox.insideXZWithRadius(vehicle);
	}
	Vector3<float> CollisionConvexHullShape::computeLocalInertia(float mass) const
	{
		AABBox<float> aabbox = toAABBox(PhysicsTransform());
		float width = 2.0 * aabbox.getHalfSize(0);
		float height = 2.0 * aabbox.getHalfSize(1);
		float depth = 2.0 * aabbox.getHalfSize(2);

		float localInertia1 = (1.0/12.0) * mass * (height*height + depth*depth);
		float localInertia2 = (1.0/12.0) * mass * (width*width + depth*depth);
		float localInertia3 = (1.0/12.0) * mass * (width*width + height*height);
		return Vector3<float>(localInertia1, localInertia2, localInertia3);
	}
Beispiel #8
0
BoundOverlap OCTree::BoundVisible(size_t index, AABBox const & aabb) const
{
    BOOST_ASSERT(index < octree_.size());

    octree_node_t const & node = octree_[index];
    if ((node.visible != BO_No) && MathLib::intersect_aabb_aabb(node.bb, aabb))
    {
        if (BO_Yes == node.visible)
        {
            return BO_Yes;
        }
        else
        {
            BOOST_ASSERT(BO_Partial == node.visible);

            if (node.first_child_index != -1)
            {
                float3 const center = node.bb.Center();
                int mark[6];
                mark[0] = aabb.Min().x() >= center.x() ? 1 : 0;
                mark[1] = aabb.Min().y() >= center.y() ? 2 : 0;
                mark[2] = aabb.Min().z() >= center.z() ? 4 : 0;
                mark[3] = aabb.Max().x() >= center.x() ? 1 : 0;
                mark[4] = aabb.Max().y() >= center.y() ? 2 : 0;
                mark[5] = aabb.Max().z() >= center.z() ? 4 : 0;
                for (int j = 0; j < 8; ++ j)
                {
                    if (j == ((j & 1) ? mark[3] : mark[0])
                            + ((j & 2) ? mark[4] : mark[1])
                            + ((j & 4) ? mark[5] : mark[2]))
                    {
                        BoundOverlap const bo = this->BoundVisible(node.first_child_index + j, aabb);
                        if (bo != BO_No)
                        {
                            return bo;
                        }
                    }
                }

                return BO_No;
            }
            else
            {
                return BO_Partial;
            }
        }
    }
    else
    {
        return BO_No;
    }
}
Beispiel #9
0
	void AABBNode::updateAABBox(float fatMargin)
	{
		if (isLeaf())
		{
			Point3<float> fatMargin3(fatMargin, fatMargin, fatMargin);
			AABBox<float> bodyBox = bodyNodeData->retrieveBodyAABBox();

			aabbox = AABBox<float>(bodyBox.getMin()-fatMargin3, bodyBox.getMax()+fatMargin3);
		}else
		{
			aabbox = children[0]->getAABBox().merge(children[1]->getAABBox());
		}
	}
void ShapeToAABBoxTest::boxConversion()
{
	CollisionBoxShape collisionBox(Vector3<float>(1.0, 2.0, 1.0)); //box 1x2x1
	PhysicsTransform transform(urchin::Point3<float>(0.0, 0.0, 0.0), //move 0 unit on X, Y and Z axis
			urchin::Quaternion<float>(urchin::Vector3<float>(0.0, 0.0, 1.0), 3.14159265358979/4)); //rotate 45° on Z axis

	AABBox<float> box = collisionBox.toAABBox(transform);

	AssertHelper::assertFloatEquals(box.getHalfSize(0), 2.12132034356);
	AssertHelper::assertFloatEquals(box.getHalfSize(1), 2.12132034356);
	AssertHelper::assertFloatEquals(box.getHalfSize(2), 1.0);
	AssertHelper::assertPoint3FloatEquals(box.getMin(), Point3<float>(-2.12132034356, -2.12132034356, -1.0));
	AssertHelper::assertPoint3FloatEquals(box.getMax(), Point3<float>(2.12132034356, 2.12132034356, 1.0));
}
Beispiel #11
0
bool ShadowPolygon::inside (const Vector2& pos, const AABBox& bbox) const {
  Vector2 corners[4];
  bbox.getCorners(pos, corners);
  for (int i=0; i<4; i++)
    if (!inside(corners[i]))
      return false;
  return true;
}
void ShapeToAABBoxTest::convexHullConversion()
{
	Point3<float> boxPointsTab[] = {
			Point3<float>(-1.0, -2.0, 1.0), Point3<float>(1.0, -2.0, 1.0), Point3<float>(1.0, 2.0, 1.0), Point3<float>(-1.0, 2.0, 1.0),
			Point3<float>(-1.0, -2.0, -1.0), Point3<float>(1.0, -2.0, -1.0), Point3<float>(1.0, 2.0, -1.0), Point3<float>(-1.0, 2.0, -1.0),
	};
	std::vector<Point3<float>> boxPoints(boxPointsTab, boxPointsTab+sizeof(boxPointsTab)/sizeof(Point3<float>));

	CollisionConvexHullShape collisionConvexHull(0.0, boxPoints);
	PhysicsTransform transform(urchin::Point3<float>(0.0, 0.0, 0.0), //move 0 unit on X, Y and Z axis
			urchin::Quaternion<float>(urchin::Vector3<float>(0.0, 0.0, 1.0), -3.14159265358979/4)); //rotate 45° on Z axis

	AABBox<float> box = collisionConvexHull.toAABBox(transform);

	AssertHelper::assertFloatEquals(box.getHalfSize(0), 2.12132034356);
	AssertHelper::assertFloatEquals(box.getHalfSize(1), 2.12132034356);
	AssertHelper::assertFloatEquals(box.getHalfSize(2), 1.0);
	AssertHelper::assertPoint3FloatEquals(box.getMin(), Point3<float>(-2.12132034356, -2.12132034356, -1.0));
	AssertHelper::assertPoint3FloatEquals(box.getMax(), Point3<float>(2.12132034356, 2.12132034356, 1.0));
}
	AABBox<float> CollisionCompoundShape::toAABBox(const PhysicsTransform &physicsTransform) const
	{
		Point3<float> rotatedTranslation = physicsTransform.getOrientation().rotatePoint(Point3<float>(localizedShapes[0]->translation));
		Point3<float> finalPosition = physicsTransform.getPosition().translate(rotatedTranslation.toVector());
		PhysicsTransform shapeWorldTransform(finalPosition, physicsTransform.getOrientation());
		AABBox<float> globalCompoundBox = localizedShapes[0]->shape->toAABBox(shapeWorldTransform);

		for(unsigned int i=1; i<localizedShapes.size(); ++i)
		{
			rotatedTranslation = physicsTransform.getOrientation().rotatePoint(Point3<float>(localizedShapes[i]->translation));
			finalPosition = physicsTransform.getPosition().translate(rotatedTranslation.toVector());
			shapeWorldTransform.setPosition(finalPosition);

			AABBox<float> compoundBox = localizedShapes[i]->shape->toAABBox(shapeWorldTransform);

			globalCompoundBox = globalCompoundBox.merge(compoundBox);
		}

		return globalCompoundBox;
	}
Beispiel #14
0
void ModelPreviewCanvas::AddjustCameraPos()
{
	_Assert(mCamera != NULL);
	_Assert(mModel != NULL);

	AABBox bound;
	mModel->CalcDynamicAABBox(IDENTITY_MATRIX, &bound);

	float width = bound.GetSize().x;
	float height = bound.GetSize().y;
	float length = bound.GetSize().z;

	float aspect = 0;
	float fov = 0;
	mCamera->GetCameraParams(NULL, NULL, &fov, &aspect);

	float distY = (height / 2.0f) / tan(fov / 2.0f);
	float distX = (height / 2.0f) / (aspect * tan(fov / 2.0f));

	float dist = Max(distX, distY);

	mCamera->SetWorldPosition(bound.GetCenter());
	mCamera->Translate(0, 0, -dist - length);
	mCamera->LookAt(bound.GetCenter());

	HoverCameraController* hoverCameraController = New HoverCameraController(5.0f, 20.0f, -4*PI/9, 4*PI/9, 
		2.0f, 1000.0f, bound.GetCenter(), dist + length);

	mCamera->SetCameraController(hoverCameraController);
}
	void FrustumShadowData::updateShadowCasterReceiverBox(const AABBox<float> &shadowCasterReceiverBox, bool forceUpdateAllShadowMap)
	{
		if(areIdenticalAABBox(shadowCasterReceiverBox, this->shadowCasterReceiverBox) && !forceUpdateAllShadowMap)
		{
			this->shadowCasterReceiverBoxUpdated = false;
		}else
		{
			this->shadowCasterReceiverBox = shadowCasterReceiverBox;
			this->lightProjectionMatrix = shadowCasterReceiverBox.toProjectionMatrix();

			this->shadowCasterReceiverBoxUpdated = true;
		}
	}
Beispiel #16
0
int Frustum::boxInFrustum(const AABBox &bbox)
{
	int result = INSIDE;
	for(unsigned int i=0; i<PLANECOUNT; i++)
	{
		if(planes[i]->isBehind(bbox.positiveVertex(planes[i]->normal)))
		{
			return OUTSIDE;
		}
	}

	return result;
}
	/**
	 * Updates frustum shadow data (models, shadow caster/receiver box, projection matrix)
	 */
	void ShadowManager::updateFrustumShadowData(const Light *const light, ShadowData *const shadowData)
	{
		if(light->hasParallelBeams())
		{ //sun light
			for(unsigned int i=0; i<splittedFrustum.size(); ++i)
			{
				AABBox<float> aabboxSceneIndependent = createSceneIndependentBox(splittedFrustum[i], light, shadowData->getLightViewMatrix());
				OBBox<float> obboxSceneIndependentViewSpace = shadowData->getLightViewMatrix().inverse() * OBBox<float>(aabboxSceneIndependent);

				const std::set<Model *> models = modelOctreeManager->getOctreeablesIn(obboxSceneIndependentViewSpace);
				shadowData->getFrustumShadowData(i)->setModels(models);

				AABBox<float> aabboxSceneDependent = createSceneDependentBox(aabboxSceneIndependent, obboxSceneIndependentViewSpace,
						models, shadowData->getLightViewMatrix());
				shadowData->getFrustumShadowData(i)->setShadowCasterReceiverBox(aabboxSceneDependent);
				shadowData->getFrustumShadowData(i)->setLightProjectionMatrix(aabboxSceneDependent.toProjectionMatrix());
			}
		}else
		{
			throw std::runtime_error("Shadow not supported on omnidirectional light.");
		}
	}
Beispiel #18
0
void Mesh::addPrimitive(unsigned indexA, unsigned indexB, unsigned indexC, Material* material)
{
    if (indexA == indexB || indexB == indexC)
    {
        return;
    }

    Triangle* newTri = new Triangle(&mVertices[indexA], &mVertices[indexB], &mVertices[indexC], material);

    const AABBox bounds = newTri->bounds();
    unsigned flatCount = 0;
    for (unsigned i = 0; i < 3; ++i)
    {
        if (bounds.ll()[i] == bounds.ur()[i]) ++flatCount;
    }

    if (flatCount > 1)
    {
        delete newTri;
        return;
    }
    
    mPrimitives.emplace_back(newTri);
}
Beispiel #19
0
void OCTree::DivideNode(size_t index, uint32_t curr_depth)
{
    if (octree_[index].obj_ptrs.size() > 1)
    {
        size_t const this_size = octree_.size();
        AABBox const parent_bb = octree_[index].bb;
        float3 const parent_center = parent_bb.Center();
        octree_[index].first_child_index = static_cast<int>(this_size);
        octree_[index].visible = BO_No;

        octree_.resize(this_size + 8);
        for (SceneObjsType::const_reference so : octree_[index].obj_ptrs)
        {
            AABBox const & aabb = *so->PosBoundWS();
            int mark[6];
            mark[0] = aabb.Min().x() >= parent_center.x() ? 1 : 0;
            mark[1] = aabb.Min().y() >= parent_center.y() ? 2 : 0;
            mark[2] = aabb.Min().z() >= parent_center.z() ? 4 : 0;
            mark[3] = aabb.Max().x() >= parent_center.x() ? 1 : 0;
            mark[4] = aabb.Max().y() >= parent_center.y() ? 2 : 0;
            mark[5] = aabb.Max().z() >= parent_center.z() ? 4 : 0;
            for (int j = 0; j < 8; ++ j)
            {
                if (j == ((j & 1) ? mark[3] : mark[0])
                        + ((j & 2) ? mark[4] : mark[1])
                        + ((j & 4) ? mark[5] : mark[2]))
                {
                    octree_[this_size + j].obj_ptrs.push_back(so);
                }
            }
        }

        for (size_t j = 0; j < 8; ++ j)
        {
            octree_node_t& new_node = octree_[this_size + j];
            new_node.first_child_index = -1;
            new_node.bb = AABBox(float3((j & 1) ? parent_center.x() : parent_bb.Min().x(),
                                        (j & 2) ? parent_center.y() : parent_bb.Min().y(),
                                        (j & 4) ? parent_center.z() : parent_bb.Min().z()),
                                 float3((j & 1) ? parent_bb.Max().x() : parent_center.x(),
                                        (j & 2) ? parent_bb.Max().y() : parent_center.y(),
                                        (j & 4) ? parent_bb.Max().z() : parent_center.z()));

            if (curr_depth < max_tree_depth_)
            {
                this->DivideNode(this_size + j, curr_depth + 1);
            }
        }

        SceneObjsType empty;
        octree_[index].obj_ptrs.swap(empty);
    }
}
bool ModelComponent::Cull(const tt::GameContext& context)
{
	tt::Vector3 vertices[8];
	tt::Matrix4x4 wvpMat = m_pTransform->GetWorldMatrix() * context.pGame->GetActiveScene()->GetActiveCamera()->GetView() * context.pGame->GetActiveScene()->GetActiveCamera()->GetProjection();
	
	AABBox aabBox = m_pModel->GetAABB();
	aabBox.GetVertices(vertices);
	
	//If one point is inside the view frustum, the bounding volume is visible
	for(unsigned int i=0; i<8; ++i){
		vertices[i] = vertices[i].TransformPoint(wvpMat);

		if( vertices[i].x >= -1 && vertices[i].x <= 1 && 
			vertices[i].y >= -1 && vertices[i].y <= 1 &&
			vertices[i].z >= 0  && vertices[i].z <= 1 )
			return false;
	}
	
	//Additional checks to make sure we don't cull edge cases	
	tt::Matrix4x4 invWvpMat = wvpMat.Inverse();
	tt::Vector3 origin[] = {tt::Vector3(-1, -1, 0),
							tt::Vector3(-1,  1, 0),
							tt::Vector3( 1, -1, 0),
							tt::Vector3( 1,  1, 0),
							};
	tt::Vector3 destination[] = {tt::Vector3(-1, -1, 1),
								 tt::Vector3(-1,  1, 1),
								 tt::Vector3( 1, -1, 1),
								 tt::Vector3( 1,  1, 1),
								 };
	tt::Vector3 direction = tt::Vector3(0,0,1).TransformVector(invWvpMat);
	
	if(aabBox.Intersect(Ray(origin[0].TransformPoint(invWvpMat), destination[0].TransformPoint(invWvpMat)), 0, 1) )
		return false;
	if(aabBox.Intersect(Ray(origin[1].TransformPoint(invWvpMat), destination[1].TransformPoint(invWvpMat)), 0, 1) )
		return false;
	if(aabBox.Intersect(Ray(origin[2].TransformPoint(invWvpMat), destination[2].TransformPoint(invWvpMat)), 0, 1) )
		return false;
	if(aabBox.Intersect(Ray(origin[3].TransformPoint(invWvpMat), destination[3].TransformPoint(invWvpMat)), 0, 1) )
		return false;

	return true;
}
Beispiel #21
0
	void SDSMCascadedShadowLayer::UpdateCascades(Camera const & camera, float4x4 const & light_view_proj,
			float3 const & light_space_border)
	{
		RenderFactory& rf = Context::Instance().RenderFactoryInstance();
		RenderEngine& re = rf.RenderEngineInstance();

		uint32_t const num_cascades = static_cast<uint32_t>(intervals_.size());
		uint32_t const copy_index = frame_index_ & 1;
		uint32_t const read_back_index = (0 == frame_index_) ? copy_index : !copy_index;

		if (cs_support_)
		{
			re.BindFrameBuffer(FrameBufferPtr());

			float max_blur_light_space = 8.0f / 1024;
			float3 max_cascade_scale(max_blur_light_space / light_space_border.x(),
				max_blur_light_space / light_space_border.y(),
				std::numeric_limits<float>::max());

			int const TILE_DIM = 128;

			int dispatch_x = (depth_tex_->Width(0) + TILE_DIM - 1) / TILE_DIM;
			int dispatch_y = (depth_tex_->Height(0) + TILE_DIM - 1) / TILE_DIM;

			*interval_buff_param_ = interval_buff_;
			*interval_buff_uint_param_ = interval_buff_;
			*interval_buff_read_param_ = interval_buff_;
			*cascade_min_buff_uint_param_ = cascade_min_buff_;
			*cascade_max_buff_uint_param_ = cascade_max_buff_;
			*cascade_min_buff_read_param_ = cascade_min_buff_;
			*cascade_max_buff_read_param_ = cascade_max_buff_;
			*scale_buff_param_ = scale_buff_;
			*bias_buff_param_ = bias_buff_;
			*depth_tex_param_ = depth_tex_;
			*num_cascades_param_ = static_cast<int32_t>(num_cascades);
			*inv_depth_width_height_param_ = float2(1.0f / depth_tex_->Width(0), 1.0f / depth_tex_->Height(0));
			*near_far_param_ = float2(camera.NearPlane(), camera.FarPlane());
			float4x4 const & inv_proj = camera.InverseProjMatrix();
			float3 upper_left = MathLib::transform_coord(float3(-1, +1, 1), inv_proj);
			float3 upper_right = MathLib::transform_coord(float3(+1, +1, 1), inv_proj);
			float3 lower_left = MathLib::transform_coord(float3(-1, -1, 1), inv_proj);
			*upper_left_param_ = upper_left;
			*xy_dir_param_ = float2(upper_right.x() - upper_left.x(), lower_left.y() - upper_left.y());
			*view_to_light_view_proj_param_ = camera.InverseViewMatrix() * light_view_proj;
			*light_space_border_param_ = light_space_border;
			*max_cascade_scale_param_ = max_cascade_scale;

			re.Dispatch(*clear_z_bounds_tech_, 1, 1, 1);
			re.Dispatch(*reduce_z_bounds_from_depth_tech_, dispatch_x, dispatch_y, 1);
			re.Dispatch(*compute_log_cascades_from_z_bounds_tech_, 1, 1, 1);
			re.Dispatch(*clear_cascade_bounds_tech_, 1, 1, 1);
			re.Dispatch(*reduce_bounds_from_depth_tech_, dispatch_x, dispatch_y, 1);
			re.Dispatch(*compute_custom_cascades_tech_, 1, 1, 1);

			interval_buff_->CopyToBuffer(*interval_cpu_buffs_[copy_index]);
			scale_buff_->CopyToBuffer(*scale_cpu_buffs_[copy_index]);
			bias_buff_->CopyToBuffer(*bias_cpu_buffs_[copy_index]);

			GraphicsBuffer::Mapper interval_mapper(*interval_cpu_buffs_[read_back_index], BA_Read_Only);
			GraphicsBuffer::Mapper scale_mapper(*scale_cpu_buffs_[read_back_index], BA_Read_Only);
			GraphicsBuffer::Mapper bias_mapper(*bias_cpu_buffs_[read_back_index], BA_Read_Only);
			float2* interval_ptr = interval_mapper.Pointer<float2>();
			float3* scale_ptr = scale_mapper.Pointer<float3>();
			float3* bias_ptr = bias_mapper.Pointer<float3>();

			for (size_t i = 0; i < intervals_.size(); ++ i)
			{
				float3 const & scale = scale_ptr[i];
				float3 const & bias = bias_ptr[i];

				intervals_[i] = interval_ptr[i];
				scales_[i] = scale;
				biases_[i] = bias;
			}
		}
		else
		{
			float2 const near_far(camera.NearPlane(), camera.FarPlane());

			reduce_z_bounds_from_depth_pp_->SetParam(1, near_far);
			reduce_z_bounds_from_depth_pp_->Apply();

			for (uint32_t i = 1; i < depth_deriative_tex_->NumMipMaps(); ++ i)
			{
				int width = depth_deriative_tex_->Width(i - 1);
				int height = depth_deriative_tex_->Height(i - 1);

				float delta_x = 1.0f / width;
				float delta_y = 1.0f / height;
				float4 delta_offset(delta_x, delta_y, -delta_x / 2, -delta_y / 2);			
				reduce_z_bounds_from_depth_mip_map_pp_->SetParam(0, delta_offset);

				reduce_z_bounds_from_depth_mip_map_pp_->OutputPin(0, depth_deriative_small_tex_, i - 1);
				reduce_z_bounds_from_depth_mip_map_pp_->Apply();

				int sw = depth_deriative_tex_->Width(i);
				int sh = depth_deriative_tex_->Height(i);

				depth_deriative_small_tex_->CopyToSubTexture2D(*depth_deriative_tex_, 0, i, 0, 0, sw, sh,
					0, i - 1, 0, 0, sw, sh);
			}

			compute_log_cascades_from_z_bounds_pp_->SetParam(1, static_cast<int32_t>(num_cascades));
			compute_log_cascades_from_z_bounds_pp_->SetParam(2, near_far);
			compute_log_cascades_from_z_bounds_pp_->Apply();

			interval_tex_->CopyToSubTexture2D(*interval_cpu_texs_[copy_index], 0, 0, 0, 0, num_cascades, 1,
				0, 0, 0, 0, num_cascades, 1);

			Texture::Mapper interval_mapper(*interval_cpu_texs_[read_back_index], 0, 0,
				TMA_Read_Only, 0, 0, num_cascades, 1);
			Vector_T<half, 2>* interval_ptr = interval_mapper.Pointer<Vector_T<half, 2> >();

			for (size_t i = 0; i < intervals_.size(); ++ i)
			{
				float2 const interval(static_cast<float>(interval_ptr[i].x()),
					static_cast<float>(interval_ptr[i].y()));

				AABBox aabb = CalcFrustumExtents(camera, interval.x(), interval.y(), light_view_proj);

				aabb &= AABBox(float3(-1, -1, -1), float3(+1, +1, +1));

				aabb.Min() -= light_space_border;
				aabb.Max() += light_space_border;

				aabb.Min().x() = +aabb.Min().x() * 0.5f + 0.5f;
				aabb.Min().y() = -aabb.Min().y() * 0.5f + 0.5f;
				aabb.Max().x() = +aabb.Max().x() * 0.5f + 0.5f;
				aabb.Max().y() = -aabb.Max().y() * 0.5f + 0.5f;

				std::swap(aabb.Min().y(), aabb.Max().y());

				float3 const scale = float3(1.0f, 1.0f, 1.0f) / (aabb.Max() - aabb.Min());
				float3 const bias = -aabb.Min() * scale;

				intervals_[i] = interval;
				scales_[i] = scale;
				biases_[i] = bias;
			}
		}

		this->UpdateCropMats();

		++ frame_index_;
	}
Beispiel #22
0
	void PSSMCascadedShadowLayer::UpdateCascades(Camera const & camera, float4x4 const & light_view_proj,
			float3 const & light_space_border)
	{
		float const range = camera.FarPlane() - camera.NearPlane();
		float const ratio = camera.FarPlane() / camera.NearPlane();

		std::vector<float> distances(intervals_.size() + 1);
		for (size_t i = 0; i < intervals_.size(); ++ i)
		{
			float p = i / static_cast<float>(intervals_.size());
			float log = camera.NearPlane() * std::pow(ratio, p);
			float uniform = camera.NearPlane() + range * p;
			distances[i] = lambda_ * (log - uniform) + uniform;
		}
		distances[intervals_.size()] = camera.FarPlane();

		for (size_t i = 0; i < intervals_.size(); ++ i)
		{
			AABBox aabb = CalcFrustumExtents(camera, distances[i], distances[i + 1],
								  light_view_proj);

			aabb &= AABBox(float3(-1, -1, -1), float3(+1, +1, +1));

			aabb.Min() -= light_space_border;
			aabb.Max() += light_space_border;

			aabb.Min().x() = +aabb.Min().x() * 0.5f + 0.5f;
			aabb.Min().y() = -aabb.Min().y() * 0.5f + 0.5f;
			aabb.Max().x() = +aabb.Max().x() * 0.5f + 0.5f;
			aabb.Max().y() = -aabb.Max().y() * 0.5f + 0.5f;

			std::swap(aabb.Min().y(), aabb.Max().y());

			float3 const scale = float3(1.0f, 1.0f, 1.0f) / (aabb.Max() - aabb.Min());
			float3 const bias = -aabb.Min() * scale;

			intervals_[i] = float2(distances[i], distances[i + 1]);
			scales_[i] = scale;
			biases_[i] = bias;
		}

		this->UpdateCropMats();
	}
	void CollisionConvexHullShape::initializeDistances()
	{
		AABBox<float> aabbox = toAABBox(PhysicsTransform());
		maxDistanceToCenter = aabbox.getMaxHalfSize();
		minDistanceToCenter = aabbox.getMinHalfSize();
	}
void COpenGLGrassRenderer::update(float fDeltaTimeInSecond, const Vector4D& camPos, const Frustum& viewFrustum, CSGPGrass* pGrass)
{
	m_vCameraPos = camPos;

	m_GrassClusterInstanceArray.clearQuick();

	if( !pGrass )
		return;

	SGPVertex_GRASS_Cluster tempData;

	CSGPTerrainChunk** pChunkEnd = pGrass->m_TerrainGrassChunks.end();
	for( CSGPTerrainChunk** pChunkStart = pGrass->m_TerrainGrassChunks.begin(); pChunkStart < pChunkEnd; pChunkStart++ )
	{
		if( !m_pRenderDevice->GetWorldSystemManager()->isTerrainChunkVisible( *pChunkStart ) )
			continue;

		for(uint32 i=0; i<(*pChunkStart)->GetGrassClusterDataCount(); i++ )
		{
			// None Flag, skip this Cluster
			uint32 nGrassSetFlag = (*pChunkStart)->GetGrassClusterData()[i].nData;
			if( nGrassSetFlag == 0 )
				continue;

			tempData.vPosition[0] = (*pChunkStart)->GetGrassClusterData()[i].fPositionX;
			tempData.vPosition[1] = (*pChunkStart)->GetGrassClusterData()[i].fPositionY;
			tempData.vPosition[2] = (*pChunkStart)->GetGrassClusterData()[i].fPositionZ;
			tempData.vPosition[3] = float( (nGrassSetFlag & 0x00FF0000) >> 16 );

			// GrassCluster is not inside the camera Frustum, skip this Cluster
			AABBox GrassClusterAABB;
			GrassClusterAABB += Vector3D(tempData.vPosition[0] - m_vDefaultGrassSize.x, tempData.vPosition[1], tempData.vPosition[2] - m_vDefaultGrassSize.x);
			GrassClusterAABB += Vector3D(tempData.vPosition[0] + m_vDefaultGrassSize.x, tempData.vPosition[1] + m_vDefaultGrassSize.y, tempData.vPosition[2] + m_vDefaultGrassSize.x);
			if( !GrassClusterAABB.Intersects(viewFrustum) )
				continue;

			// GrassCluster is too far from the Grass Far Fading distance, skip this Cluster
			float fGrassDis = (m_vCameraPos - Vector4D(tempData.vPosition[0], tempData.vPosition[1], tempData.vPosition[2])).GetLength();
			if( fGrassDis > CSGPWorldConfig::getInstance()->m_fGrassFarFadingEnd )
				continue;

			// Too many grass Cluster
			if( m_GrassClusterInstanceArray.size() + 1 > INIT_GRASSCLUSTERINSTANCE_NUM )
				continue;

			tempData.vPackedNormal[0] = (uint8)(((*pChunkStart)->GetGrassClusterData()[i].nPackedNormal & 0xFF000000) >> 24);
			tempData.vPackedNormal[1] = (uint8)(((*pChunkStart)->GetGrassClusterData()[i].nPackedNormal & 0x00FF0000) >> 16);
			tempData.vPackedNormal[2] = (uint8)(((*pChunkStart)->GetGrassClusterData()[i].nPackedNormal & 0x0000FF00) >> 8);
			tempData.vPackedNormal[3] = (uint8)((nGrassSetFlag & 0xFF000000) >> 24);

			tempData.vColor[0] = tempData.vColor[1] = tempData.vColor[2] = 1.0f;
			tempData.vColor[3] = 1.0f - jlimit(0.0f, 1.0f, (fGrassDis - CSGPWorldConfig::getInstance()->m_fGrassFarFadingStart) / (CSGPWorldConfig::getInstance()->m_fGrassFarFadingEnd - CSGPWorldConfig::getInstance()->m_fGrassFarFadingStart));
			
			tempData.vWindParams[0] = ((nGrassSetFlag & 0x0000FF00) >> 8) / 255.0f;
			tempData.vWindParams[1] = 0.0f;
			tempData.vWindParams[2] = (nGrassSetFlag & 0x000000FF) / 255.0f;
			tempData.vWindParams[3] = 0.0f;

			m_GrassClusterInstanceArray.add( tempData );
		}
	}

	// update grass rendering params
	m_vTimeParams.x += fDeltaTimeInSecond;
	m_vTimeParams.y = pGrass->m_fGrassPeriod;
	m_vLightMapTextureDimision.Set(
		1.0f / m_pRenderDevice->GetWorldSystemManager()->getTerrain()->GetTerrainWidth(),
		1.0f / m_pRenderDevice->GetWorldSystemManager()->getTerrain()->GetTerrainWidth() );
	m_vWindDirForce = pGrass->m_vWindDirectionAndStrength;
}
Beispiel #25
0
void ShadowMapRenderer::setupVirtualLightCamera(Camera* camera, DirectionalLightNode* lightNode, int cascadeIndex)
{
	const float BOUND_EXPAND_FACTOR = 0.8f;

	_Assert(camera != NULL);
	_Assert(cascadeIndex >= 0 && cascadeIndex < CASCADE_COUNTS);

	DirectionalLight* dirLight = lightNode->GetDirLight();
	Vector3 lightDir = dirLight->GetDirection();
	lightDir.Normalize();

	Vector3 frustumPos[5];
	{
		float farZ = 0;
		float aspect = 0;
		float fov = 0;

		camera->GetCameraParams(NULL, &farZ, &fov, &aspect);
		farZ *= calcCascadeDist(cascadeIndex);


		float fy = farZ * tanf(fov / 2.0f);
		float fx = aspect * fy;

		frustumPos[0] = Vector3::Zero;
		frustumPos[1] = Vector3(-fx,  fy, farZ);
		frustumPos[2] = Vector3( fx,  fy, farZ);
		frustumPos[3] = Vector3(-fx, -fy, farZ);
		frustumPos[4] = Vector3( fx, -fy, farZ);
	}

	D3DXMATRIX matCameraViewInv;
	D3DXMatrixInverse(&matCameraViewInv, 0, &camera->ViewMatrix());

	D3DXMATRIX matLightView;
	{
		Vector3 lightPos = lightNode->GetWorldPosition();

		D3DXMATRIX matRotTranspose, matTransInverse;
		D3DXMatrixTranspose(&matRotTranspose, &(lightNode->GetWorldOrient().Matrix()));
		D3DXMatrixTranslation(&matTransInverse, -lightPos.x, -lightPos.y, -lightPos.z);
		matLightView = matTransInverse * matRotTranspose; 
	}

	AABBox lightSpaceBound;
	for(int i = 0; i < 5; ++i)
	{
		Vector3 posW = PosVecTransform(frustumPos[i], matCameraViewInv);
		Vector3	posL = PosVecTransform(posW, matLightView);	

		lightSpaceBound = AABBox::CombinePoint(lightSpaceBound, posL);
	}

	float nearZ = 0.1f;
	float farZ = 0;
	float width = 0;
	float height = 0;
	{
		Vector3 lookDir = camera->GetWorldForward();
		lookDir.Normalize();

		float adjustFactor = lookDir.Dot(lightDir);		// lookDir与lightDir贴近时, 向后扩展virtualCamera范围
		float expandDist = adjustFactor * BOUND_EXPAND_FACTOR * fabsf(lightSpaceBound.mMax.z - lightSpaceBound.mMin.z);

		Vector3 centerL = lightSpaceBound.GetCenter();
		D3DXMATRIX matLightViewInv;
		D3DXMatrixInverse(&matLightViewInv, 0, &matLightView);

		Vector3 centerW = PosVecTransform(centerL, matLightViewInv);
		float lightDist = fabsf(lightSpaceBound.mMax.z - lightSpaceBound.mMin.z) / 2.0f;
		width = fabsf(lightSpaceBound.mMax.x - lightSpaceBound.mMin.x);
		height = fabsf(lightSpaceBound.mMax.y - lightSpaceBound.mMin.y);

		farZ = 2.0f * lightDist + expandDist;
		mVirtualCamera[cascadeIndex].pos = centerW - (lightDist + expandDist) * lightDir;
	}

	D3DXMATRIX matLightProj;
	D3DXMatrixOrthoLH(&matLightProj, width, height, nearZ, farZ);

	D3DXMATRIX matVirtualCameraView;
	{
		Vector3 virtualCameraPos = mVirtualCamera[cascadeIndex].pos;

		D3DXMATRIX matRotTranspose, matTransInverse;
		D3DXMatrixTranspose(&matRotTranspose, &(lightNode->GetWorldOrient().Matrix()));
		D3DXMatrixTranslation(&matTransInverse, -virtualCameraPos.x, -virtualCameraPos.y, -virtualCameraPos.z);
		matVirtualCameraView = matTransInverse * matRotTranspose; 

		mVirtualCamera[cascadeIndex].bound = AABBox::MatTransform(AABBox(Vector3(0, 0, farZ/2.0f), width, height, farZ), 
			InversedMatrix(matVirtualCameraView));
	}

	mVirtualCamera[cascadeIndex].matVP = matVirtualCameraView * matLightProj;
}
Beispiel #26
0
void Renderer::fitViewNearFarToObjects(Float2& near_far,
                                       const Float4x4& view, const float near_min, const float far_max,
                                       const bool inc_light_vols) const {
    near_far.set(near_min, far_max);
    return;

    // Note, the fitting is NOT tight.   Firstly, we're using the geometry's
    // axis aligned bounding box, which is not tight (after the model
    // transform) then we're assuming the size of the box is maximum after
    // rotation into the camera space (which is also not tight).

    // Recall: OpenGL convention is to look down the negative Z axis,
    //         therefore, more negative values are actually further away.
    near_far[0] = -std::numeric_limits<float>::infinity();  // znear
    near_far[1] = std::numeric_limits<float>::infinity();  // zfar

    float min_z, max_z;

    gm_->renderStackReset();
    while (!gm_->renderStackEmpty()) {
        GeometryInstance* cur_geometry = gm_->renderStackPop();
        AABBox* aabbox = cur_geometry->aabbox();
        if (aabbox) {
            aabbox->calcMinMaxZBoundInViewSpace(min_z, max_z, view);
            if (max_z < near_far[1]) {
                near_far[1] = max_z;
            }
            if (min_z > near_far[0]) {
                near_far[0] = min_z;
            }
        }
    }

    // Also fit to light geometry:
    if (inc_light_vols) {
        Float3 pos_source;
        Float3 dir;
        float rad;
        Float3 center_view;
        LightPoint* light_point;
        LightSpot* light_spot;
        for (uint32_t i = 0; i < lighting_->lights().size(); i++) {
            switch (lighting_->lights()[i]->type()) {
            case LIGHT_POINT:
                light_point = (LightPoint*)(lighting_->lights()[i]);
                // Calculate model view projection matrix
                Float3::affineTransformPos(center_view, view,
                                           light_point->pos_world());
                rad = light_point->outside_rad();
                if ((center_view[2] - rad) < near_far[1]) {
                    near_far[1] = center_view[2] - rad;
                }
                if ((center_view[2] + rad) > near_far[0]) {
                    near_far[0] = center_view[2] + rad;
                }
                break;
            case LIGHT_SPOT_VSM:
            case LIGHT_SPOT:
                light_spot = (LightSpot*)(lighting_->lights()[i]);
                // Check the source point
                Float3::affineTransformPos(pos_source, view,
                                           light_spot->pos_world());
                if (pos_source[2] < near_far[1]) {
                    near_far[1] = pos_source[2];
                }
                if (pos_source[2] > near_far[0]) {
                    near_far[0] = pos_source[2];
                }
                // Now check the cone end
                Float3::affineTransformPos(center_view, view,
                                           light_spot->cone_center_world());
                rad = light_spot->cone_outside_radius();
                if ((center_view[2] - rad) < near_far[1]) {
                    near_far[1] = center_view[2] - rad;
                }
                if ((center_view[2] + rad) > near_far[0]) {
                    near_far[0] = center_view[2] + rad;
                }
                break;
            default:
                break;
            }
        }
    }

    near_far[0] += LOOSE_EPSILON;
    near_far[1] -= LOOSE_EPSILON;

    // now clamp the near and far to the user defined values
    if (near_far[0] > near_min) {
        near_far[0] = near_min;
    }
    if (near_far[1] < far_max) {
        near_far[1] = far_max;
    }
    if (near_far[1] > near_far[0]) {
        near_far[1] = near_far[0] - 0.1f;
    }
}
	/**
	 * @return Box in light space containing shadow caster and receiver (scene dependent)
	 */
	AABBox<float> ShadowManager::createSceneDependentBox(const AABBox<float> &aabboxSceneIndependent, const OBBox<float> &obboxSceneIndependentViewSpace,
			const std::set<Model *> &models, const Matrix4<float> &lightViewMatrix) const
	{
		AABBox<float> aabboxSceneDependent;
		bool boxInitialized = false;

		AABBox<float> aabboxSceneIndependentViewSpace = obboxSceneIndependentViewSpace.toAABBox();

		for(std::set<Model *>::iterator it = models.begin(); it!=models.end(); ++it)
		{
			const Model* model = *it;
			if(model->isProduceShadow())
			{
				const std::vector<AABBox<float>> &splittedAABBox = model->getSplittedAABBox();
				for(unsigned int i=0; i<splittedAABBox.size(); ++i)
				{
					if(splittedAABBox.size()==1 || obboxSceneIndependentViewSpace.collideWithAABBox(splittedAABBox[i]))
					{
						if(boxInitialized)
						{
							aabboxSceneDependent = aabboxSceneDependent.merge(lightViewMatrix * splittedAABBox[i]);
						}else
						{
							aabboxSceneDependent = lightViewMatrix * splittedAABBox[i];
							boxInitialized = true;
						}
					}
				}
			}
		}

		Point3<float> cutMin(
			aabboxSceneDependent.getMin().X<aabboxSceneIndependent.getMin().X ? aabboxSceneIndependent.getMin().X : aabboxSceneDependent.getMin().X,
			aabboxSceneDependent.getMin().Y<aabboxSceneIndependent.getMin().Y ? aabboxSceneIndependent.getMin().Y : aabboxSceneDependent.getMin().Y,
			aabboxSceneIndependent.getMin().Z); //shadow can be projected outside the box: value cannot be capped

		Point3<float> cutMax(
			aabboxSceneDependent.getMax().X>aabboxSceneIndependent.getMax().X ? aabboxSceneIndependent.getMax().X : aabboxSceneDependent.getMax().X,
			aabboxSceneDependent.getMax().Y>aabboxSceneIndependent.getMax().Y ? aabboxSceneIndependent.getMax().Y : aabboxSceneDependent.getMax().Y,
			aabboxSceneDependent.getMax().Z>aabboxSceneIndependent.getMax().Z ? aabboxSceneIndependent.getMax().Z : aabboxSceneDependent.getMax().Z);

		cutMin.X = (cutMin.X<0.0f) ? cutMin.X-(lightViewOverflowStepSize+fmod(cutMin.X, lightViewOverflowStepSize)) : cutMin.X-fmod(cutMin.X, lightViewOverflowStepSize);
		cutMin.Y = (cutMin.Y<0.0f) ? cutMin.Y-(lightViewOverflowStepSize+fmod(cutMin.Y, lightViewOverflowStepSize)) : cutMin.Y-fmod(cutMin.Y, lightViewOverflowStepSize);
		cutMin.Z = (cutMin.Z<0.0f) ? cutMin.Z-(lightViewOverflowStepSize+fmod(cutMin.Z, lightViewOverflowStepSize)) : cutMin.Z-fmod(cutMin.Z, lightViewOverflowStepSize);
		cutMax.X = (cutMax.X<0.0f) ? cutMax.X-fmod(cutMax.X, lightViewOverflowStepSize) : cutMax.X+(lightViewOverflowStepSize-fmod(cutMax.X, lightViewOverflowStepSize));
		cutMax.Y = (cutMax.Y<0.0f) ? cutMax.Y-fmod(cutMax.Y, lightViewOverflowStepSize) : cutMax.Y+(lightViewOverflowStepSize-fmod(cutMax.Y, lightViewOverflowStepSize));
		cutMax.Z = (cutMax.Z<0.0f) ? cutMax.Z-fmod(cutMax.Z, lightViewOverflowStepSize) : cutMax.Z+(lightViewOverflowStepSize-fmod(cutMax.Z, lightViewOverflowStepSize));

		return AABBox<float>(cutMin, cutMax);
	}
Beispiel #28
0
	bool operator()(AABBox a, AABBox b)
	{
		return (a.mortonCentroid() < b.mortonCentroid());
	}
Beispiel #29
0
bool BVH::compareBoxMorton(AABBox a, AABBox b)
{
	return a.mortonCentroid() < b.mortonCentroid();
}