const Vec3& GetPosition() const { if (mOverridingCamera){ return mOverridingCamera->GetPosition(); } return mTransformation.GetTranslation(); }
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; }
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); }
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(); }
//---------------------------------------------------------------------------- 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(); }
//---------------------------------------------------------------------------- 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(); } }
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); }