예제 #1
0
	const Vec3& GetPosition() const
	{
		if (mOverridingCamera){
			return mOverridingCamera->GetPosition();
		}
		return mTransformation.GetTranslation();
	}
예제 #2
0
void SpatialObject::SetLocation(const Transformation& t){
	mBoundingVolumeWorld->SetCenter(mBoundingVolume->GetCenter() + t.GetTranslation());
	mBoundingVolumeWorld->SetRadius(mBoundingVolume->GetRadius() * t.GetScale().GetMax());
	mLocation = t;
	if (mAnimatedLocation){
		*mAnimatedLocation = mLocation * mAnim->GetResult();
	}
	mTransformChanged = true;
}
예제 #3
0
void BVaabb::TransformBy(const Transformation& transform,
	BoundingVolumePtr result)
{
	assert(result);
	BVaabb* pNewBound = (BVaabb*)result.get();
	AABB newAABB = mAABB;
	newAABB.Translate(transform.GetTranslation());
	pNewBound->SetAABB(newAABB);
}
예제 #4
0
	void SetPosition(const Vec3& pos)
	{
		if (mOverridingCamera){
			mOverridingCamera->SetPosition(pos);
			return;
		}
		if (mTransformation.GetTranslation() == pos)
			return;
		mTransformation.SetTranslation(pos);
		mViewPropertyChanged = true;
	}
	void GatherPointLightData(const BoundingVolume* aabb, const Transformation& transform, POINT_LIGHT_CONSTANTS* plConst)
	{
		struct GatheredData
		{
			GatheredData(Real distSQ, unsigned idx)
				:mDistanceSQ(distSQ), mIndex(idx)
			{

			}
			Real mDistanceSQ;
			unsigned mIndex;
		};
		static std::vector<GatheredData> gathered;
		gathered.reserve(50);

		unsigned i = 0;
		for (auto it = mPointLights.begin(); it != mPointLights.end(); /**/)
		{		
			IteratingWeakContainer(mPointLights, it, p);
			if (!p->GetEnabled())
				continue;
			Ray3 ray(p->GetPosition(), transform.GetTranslation() - p->GetPosition());
			Ray3 localRay = transform.ApplyInverse(ray);
			auto iresult = localRay.Intersects(aabb);
			Real distSQ = Squared(iresult.second);
			Real range = p->GetRange();
			if (distSQ < (range*range))
			{
				gathered.push_back(GatheredData(distSQ, i));
			}
			++i;
		}

		std::sort(gathered.begin(), gathered.end(), [](const GatheredData& a, const GatheredData& b){
			return a.mDistanceSQ < b.mDistanceSQ;
		}
		);

		plConst->gPointLightColor[0].w = 0;
		int count = std::min(3, (int)gathered.size());
		unsigned validNumber = 0;
		for (int i = 0; i < count; i++)
		{
			PointLightPtr p = mPointLights[gathered[i].mIndex].lock();
			if (p){
				plConst->gPointLightPos[validNumber] = Vec4(p->GetPosition(), p->GetRange());
				plConst->gPointLightColor[validNumber] = Vec4(p->GetColorPowered(), (Real)count);
				++validNumber;
			}
		}

		gathered.clear();
	}
예제 #6
0
	//----------------------------------------------------------------------------
	Ray3 ScreenPosToRay(long x, long y)
	{
		Update();
		auto it = mRayCache.Find(Vec2I(x, y));
		if (it != mRayCache.end()){
			return it->second;
		}

		Real fx = 2.0f * x / GetWidth() - 1.0f;
		Real fy = 1.0f - 2.0f * y / GetHeight();
		Vec3 screenPos((Real)fx, (Real)fy, -1.0f);
		Vec3 screenMidPos((Real)fx, (Real)fy, 0.0f);
		Vec3 origin = mMatrices[InverseViewProj]* screenPos;
		Vec3 target = mMatrices[InverseViewProj] * screenMidPos;
		Vec3 dir = target - origin;
		dir.Normalize();

		Ray3 ray(mTransformation.GetTranslation(), dir);
		mRayCache[Vec2I(x, y)] = ray;
		return ray;
	}
	Vec3 GetOffset() const{
		return mTransformation.GetTranslation();
	}
예제 #8
0
	//----------------------------------------------------------------------------
	void Update()
	{
		if (mOverridingCamera){
			mOverridingCamera->Update();
		}
		// world coordinates (Blender style)
		// x: right
		// y: forward
		// z: up
		bool viewChanged = mViewPropertyChanged;
		if (mViewPropertyChanged)
		{
			mViewPropertyChanged = false;
			Vec3 right = mTransformation.GetMatrix().Column(0);
			Vec3 forward = mTransformation.GetMatrix().Column(1);
			Vec3 up = mTransformation.GetMatrix().Column(2);
			const Vec3& pos = mTransformation.GetTranslation();
			mMatrices[View] = fb::MakeViewMatrix(pos, right, forward, up);			
			mTransformation.GetHomogeneous(mMatrices[InverseView]);
			mFrustum.mOrigin = mTransformation.GetTranslation();
			mFrustum.mOrientation = mTransformation.GetRotation();
		}

		bool projChanged = mProjPropertyChanged;
		if (mProjPropertyChanged)
		{
			mAspectRatio = GetWidth() / (Real)GetHeight();
			mProjPropertyChanged = false;
			if (!mOrthogonal)
			{
				mMatrices[ProjBeforeSwap] = mMatrices[Proj] = 
					MakeProjectionMatrix(mFov, mAspectRatio, mNear, mFar);
			}
			else
			{
				mMatrices[ProjBeforeSwap] = mMatrices[Proj] = 
					MakeOrthogonalMatrix((Real)mOrthogonalData.left, (Real)mOrthogonalData.top,
					(Real)mOrthogonalData.right, (Real)mOrthogonalData.bottom,
					mNear, mFar);
			}
			if (mYZSwap)
			{
				Mat44 swapMat(
					1, 0, 0, 0,
					0, 0, 1, 0,
					0, 1, 0, 0,
					0, 0, 0, 1);
				mMatrices[Proj] = mMatrices[Proj] * swapMat;
			}
			mMatrices[InverseProj] = mMatrices[Proj].Inverse();	
			mFrustum.SetData(mNear, mFar, mFov, mAspectRatio);
		}

		if (projChanged || viewChanged)
		{
			
			mMatrices[ViewProj] = mMatrices[Proj] * mMatrices[View];
			mMatrices[InverseViewProj] = mMatrices[ViewProj].Inverse();

			UpdateFrustum();

			if (viewChanged && !mSelf->mObservers_.empty()){
				auto& observers = mSelf->mObservers_[TransformChanged];
				for (auto it = observers.begin(); it != observers.end(); /**/){
					auto observer = it->lock();
					if (!observer){
						it = observers.erase(it);
						continue;
					}
					++it;
					observer->OnViewMatrixChanged();
				}				
			}
			if (projChanged && !mSelf->mObservers_.empty()){
				auto& observers = mSelf->mObservers_[TransformChanged];
				for (auto it = observers.begin(); it != observers.end(); /**/){
					auto observer = it->lock();
					if (!observer){
						it = observers.erase(it);
						continue;
					}
					++it;
					observer->OnProjMatrixChanged();
				}
			}		
			mRayCache.clear();
		}
	}
예제 #9
0
void MeshObject::UpdateModelViewTransformation(Transformation const & model_view)
{
	// TODO: _scale and _local_transformation constitutes way too much transformation data
	Transformation transformation(model_view.GetTranslation(), model_view.GetRotation(), _scale);
	SetModelViewTransformation(transformation);
}