Perfectly working abs pos caching using dirty flags! :D
This commit is contained in:
@@ -56,7 +56,6 @@ struct ComponentWrapper
|
|||||||
|
|
||||||
void SetAllDirty(const std::string& fieldName, bool dirty = true)
|
void SetAllDirty(const std::string& fieldName, bool dirty = true)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("DIRTY: %s %s", Info.Name.c_str(), fieldName.c_str());
|
|
||||||
for (auto& kv : *DirtyBitField) {
|
for (auto& kv : *DirtyBitField) {
|
||||||
SetDirty(kv.first, fieldName);
|
SetDirty(kv.first, fieldName);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
namespace Transform
|
namespace Transform
|
||||||
{
|
{
|
||||||
|
|
||||||
glm::mat4 AbsoluteTransformation(EntityWrapper entity);
|
//glm::mat4 AbsoluteTransformation(EntityWrapper entity);
|
||||||
glm::vec3 AbsolutePosition(EntityWrapper entity);
|
glm::vec3 AbsolutePosition(EntityWrapper entity);
|
||||||
glm::vec3 AbsolutePosition(World* world, EntityID entity);
|
glm::vec3 AbsolutePosition(World* world, EntityID entity);
|
||||||
glm::vec3 AbsoluteOrientationEuler(EntityWrapper entity);
|
glm::vec3 AbsoluteOrientationEuler(EntityWrapper entity);
|
||||||
@@ -20,6 +20,11 @@ glm::mat4 ModelMatrix(EntityWrapper entity);
|
|||||||
glm::mat4 ModelMatrix(EntityID entity, World* world);
|
glm::mat4 ModelMatrix(EntityID entity, World* world);
|
||||||
glm::vec3 TransformPoint(const glm::vec3& point, const glm::mat4& matrix);
|
glm::vec3 TransformPoint(const glm::vec3& point, const glm::mat4& matrix);
|
||||||
|
|
||||||
|
|
||||||
|
extern int RecalculatedPositions;
|
||||||
|
extern int RecalculatedOrientations;
|
||||||
|
extern int RecalculatedScales;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -638,7 +638,7 @@ boost::optional<EntityAABB> EntityAbsoluteAABB(EntityWrapper& entity, bool takeM
|
|||||||
return boost::none;
|
return boost::none;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 modelMat = Transform::AbsoluteTransformation(entity);
|
glm::mat4 modelMat = Transform::ModelMatrix(entity);
|
||||||
glm::vec3 mini(INFINITY);
|
glm::vec3 mini(INFINITY);
|
||||||
glm::vec3 maxi(-INFINITY);
|
glm::vec3 maxi(-INFINITY);
|
||||||
glm::vec3 maxCorner = modelSpaceBox.MaxCorner();
|
glm::vec3 maxCorner = modelSpaceBox.MaxCorner();
|
||||||
|
|||||||
@@ -2,32 +2,29 @@
|
|||||||
|
|
||||||
namespace Transform
|
namespace Transform
|
||||||
{
|
{
|
||||||
struct Values
|
|
||||||
{
|
|
||||||
glm::vec3 Position;
|
|
||||||
glm::quat Orientation;
|
|
||||||
glm::vec3 Scale;
|
|
||||||
Values()
|
|
||||||
: Position()
|
|
||||||
, Orientation()
|
|
||||||
, Scale(1.f)
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
std::unordered_map<EntityWrapper, Values> Cache;
|
std::unordered_map<EntityWrapper, glm::vec3> PositionCache;
|
||||||
|
std::unordered_map<EntityWrapper, glm::quat> OrientationCache;
|
||||||
|
std::unordered_map<EntityWrapper, glm::vec3> ScaleCache;
|
||||||
|
std::unordered_map<EntityWrapper, glm::mat4> MatrixCache;
|
||||||
|
|
||||||
|
int RecalculatedPositions = 0;
|
||||||
|
int RecalculatedOrientations = 0;
|
||||||
|
int RecalculatedScales = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 Transform::AbsoluteTransformation(EntityWrapper entity)
|
//glm::mat4 Transform::AbsoluteTransformation(EntityWrapper entity)
|
||||||
{
|
//{
|
||||||
glm::mat4 t = glm::mat4(1.f);
|
// glm::mat4 t = glm::mat4(1.f);
|
||||||
|
//
|
||||||
while (entity.Valid()) {
|
// while (entity.Valid()) {
|
||||||
t = glm::translate((const glm::vec3&)entity["Transform"]["Position"]) * glm::toMat4(glm::quat((const glm::vec3&)entity["Transform"]["Orientation"])) * glm::scale((const glm::vec3&)entity["Transform"]["Scale"]) * t;
|
// t = glm::translate((const glm::vec3&)entity["Transform"]["Position"]) * glm::toMat4(glm::quat((const glm::vec3&)entity["Transform"]["Orientation"])) * glm::scale((const glm::vec3&)entity["Transform"]["Scale"]) * t;
|
||||||
entity = entity.Parent();
|
// entity = entity.Parent();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
return t;
|
// return t;
|
||||||
}
|
//}
|
||||||
|
|
||||||
glm::vec3 Transform::AbsolutePosition(World* world, EntityID entity)
|
glm::vec3 Transform::AbsolutePosition(World* world, EntityID entity)
|
||||||
{
|
{
|
||||||
@@ -36,32 +33,30 @@ glm::vec3 Transform::AbsolutePosition(World* world, EntityID entity)
|
|||||||
|
|
||||||
glm::vec3 Transform::AbsolutePosition(EntityWrapper entity)
|
glm::vec3 Transform::AbsolutePosition(EntityWrapper entity)
|
||||||
{
|
{
|
||||||
glm::vec3 position;
|
|
||||||
if (!entity.Valid()) {
|
if (!entity.Valid()) {
|
||||||
|
return glm::vec3();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto cacheIt = PositionCache.find(entity);
|
||||||
|
ComponentWrapper cTransform = entity["Transform"];
|
||||||
|
ComponentWrapper::SubscriptProxy cTransformPosition = cTransform["Position"];
|
||||||
|
if (cacheIt != PositionCache.end() && !cTransformPosition.Dirty(DirtySetType::Transform)) {
|
||||||
|
return cacheIt->second;
|
||||||
|
} else {
|
||||||
|
EntityWrapper parent = entity.Parent();
|
||||||
|
// Calculate position
|
||||||
|
glm::vec3 position = AbsolutePosition(parent) + Transform::AbsoluteScale(parent) * (Transform::AbsoluteOrientation(parent) * (const glm::vec3&)cTransformPosition);
|
||||||
|
// Cache it
|
||||||
|
PositionCache[entity] = position;
|
||||||
|
RecalculatedPositions++;
|
||||||
|
// Unset dirty flag
|
||||||
|
cTransformPosition.SetDirty(DirtySetType::Transform, false);
|
||||||
|
// Flag children as dirty
|
||||||
|
for (auto& child : entity.ChildrenWithComponent("Transform")) {
|
||||||
|
child["Transform"]["Position"].SetDirty(DirtySetType::Transform, true);
|
||||||
|
}
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
ComponentWrapper entityTransform = entity["Transform"];
|
|
||||||
if (!entityTransform["Position"].Dirty(DirtySet::Transform)) {
|
|
||||||
return Cache[entity].Position;
|
|
||||||
}
|
|
||||||
|
|
||||||
EntityWrapper e = entity;
|
|
||||||
while (e.Valid()) {
|
|
||||||
ComponentWrapper transform = e["Transform"];
|
|
||||||
EntityWrapper parent = e.Parent();
|
|
||||||
position += Transform::AbsoluteOrientation(parent) * (glm::vec3)transform["Position"];
|
|
||||||
e = parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
Cache[entity].Position = position;
|
|
||||||
entityTransform["Position"].SetDirty(false);
|
|
||||||
|
|
||||||
auto dirtyChildren = entity.ChildrenWithComponent("Transform");
|
|
||||||
for (auto& child : dirtyChildren) {
|
|
||||||
child["Transform"]["Position"].SetDirty(true);
|
|
||||||
}
|
|
||||||
return position;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 Transform::AbsoluteOrientationEuler(EntityWrapper entity)
|
glm::vec3 Transform::AbsoluteOrientationEuler(EntityWrapper entity)
|
||||||
@@ -84,30 +79,30 @@ glm::quat Transform::AbsoluteOrientation(World* world, EntityID entity)
|
|||||||
|
|
||||||
glm::quat Transform::AbsoluteOrientation(EntityWrapper entity)
|
glm::quat Transform::AbsoluteOrientation(EntityWrapper entity)
|
||||||
{
|
{
|
||||||
glm::quat orientation;
|
|
||||||
if (!entity.Valid()) {
|
if (!entity.Valid()) {
|
||||||
|
return glm::quat();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto cacheIt = OrientationCache.find(entity);
|
||||||
|
ComponentWrapper cTransform = entity["Transform"];
|
||||||
|
ComponentWrapper::SubscriptProxy cTransformOrientation = cTransform["Orientation"];
|
||||||
|
if (cacheIt != OrientationCache.end() && !cTransformOrientation.Dirty(DirtySetType::Transform)) {
|
||||||
|
return cacheIt->second;
|
||||||
|
} else {
|
||||||
|
EntityWrapper parent = entity.Parent();
|
||||||
|
// Calculate orientation
|
||||||
|
glm::quat orientation = AbsoluteOrientation(parent) * glm::quat((const glm::vec3&)cTransformOrientation);
|
||||||
|
// Cache it
|
||||||
|
OrientationCache[entity] = orientation;
|
||||||
|
RecalculatedOrientations++;
|
||||||
|
// Unset dirty flag
|
||||||
|
cTransformOrientation.SetDirty(DirtySetType::Transform, false);
|
||||||
|
// Flag children as dirty
|
||||||
|
for (auto& child : entity.ChildrenWithComponent("Transform")) {
|
||||||
|
child["Transform"]["Orientation"].SetDirty(DirtySetType::Transform, true);
|
||||||
|
}
|
||||||
return orientation;
|
return orientation;
|
||||||
}
|
}
|
||||||
ComponentWrapper entityTransform = entity["Transform"];
|
|
||||||
if (!entityTransform["Orientation"].Dirty(DirtySet::Transform)) {
|
|
||||||
return Cache[entity].Orientation;
|
|
||||||
}
|
|
||||||
|
|
||||||
EntityWrapper e = entity;
|
|
||||||
while (e.Valid()) {
|
|
||||||
ComponentWrapper transform = e["Transform"];
|
|
||||||
orientation = glm::quat((glm::vec3)transform["Orientation"]) * orientation;
|
|
||||||
e = e.Parent();
|
|
||||||
}
|
|
||||||
|
|
||||||
Cache[entity].Orientation = orientation;
|
|
||||||
entityTransform["Orientation"].SetDirty(false);
|
|
||||||
|
|
||||||
auto dirtyChildren = entity.ChildrenWithComponent("Transform");
|
|
||||||
for (auto& child : dirtyChildren) {
|
|
||||||
child["Transform"]["Orientation"].SetDirty(true);
|
|
||||||
}
|
|
||||||
return orientation;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 Transform::AbsoluteScale(World* world, EntityID entity)
|
glm::vec3 Transform::AbsoluteScale(World* world, EntityID entity)
|
||||||
@@ -117,41 +112,40 @@ glm::vec3 Transform::AbsoluteScale(World* world, EntityID entity)
|
|||||||
|
|
||||||
glm::vec3 Transform::AbsoluteScale(EntityWrapper entity)
|
glm::vec3 Transform::AbsoluteScale(EntityWrapper entity)
|
||||||
{
|
{
|
||||||
glm::vec3 scale(1.f);
|
|
||||||
if (!entity.Valid()) {
|
if (!entity.Valid()) {
|
||||||
|
return glm::vec3(1.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto cacheIt = ScaleCache.find(entity);
|
||||||
|
ComponentWrapper cTransform = entity["Transform"];
|
||||||
|
ComponentWrapper::SubscriptProxy cTransformScale = cTransform["Scale"];
|
||||||
|
if (cacheIt != ScaleCache.end() && !cTransformScale.Dirty(DirtySetType::Transform)) {
|
||||||
|
return cacheIt->second;
|
||||||
|
} else {
|
||||||
|
EntityWrapper parent = entity.Parent();
|
||||||
|
// Calculate scale
|
||||||
|
glm::vec3 scale = AbsoluteScale(parent) * (const glm::vec3&)cTransformScale;
|
||||||
|
// Cache it
|
||||||
|
ScaleCache[entity] = scale;
|
||||||
|
RecalculatedPositions++;
|
||||||
|
// Unset dirty flag
|
||||||
|
cTransformScale.SetDirty(DirtySetType::Transform, false);
|
||||||
|
// Flag children as dirty
|
||||||
|
for (auto& child : entity.ChildrenWithComponent("Transform")) {
|
||||||
|
child["Transform"]["Scale"].SetDirty(DirtySetType::Transform, true);
|
||||||
|
}
|
||||||
return scale;
|
return scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
ComponentWrapper entityTransform = entity["Transform"];
|
|
||||||
if (!entityTransform["Scale"].Dirty(DirtySet::Transform)) {
|
|
||||||
return Cache[entity].Scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
EntityWrapper e = entity;
|
|
||||||
while (e.Valid()) {
|
|
||||||
ComponentWrapper transform = e["Transform"];
|
|
||||||
scale *= (glm::vec3)transform["Scale"];
|
|
||||||
e = e.Parent();
|
|
||||||
}
|
|
||||||
|
|
||||||
Cache[entity].Scale = scale;
|
|
||||||
entityTransform["Scale"].SetDirty(false);
|
|
||||||
|
|
||||||
auto dirtyChildren = entity.ChildrenWithComponent("Transform");
|
|
||||||
for (auto& child : dirtyChildren) {
|
|
||||||
child["Transform"]["Scale"].SetDirty(true);
|
|
||||||
}
|
|
||||||
return scale;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 Transform::ModelMatrix(EntityID entity, World* world)
|
glm::mat4 Transform::ModelMatrix(EntityID entityID, World* world)
|
||||||
{
|
{
|
||||||
return AbsoluteTransformation(EntityWrapper(world, entity));
|
return ModelMatrix(EntityWrapper(world, entityID));
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 Transform::ModelMatrix(EntityWrapper entity)
|
glm::mat4 Transform::ModelMatrix(EntityWrapper entity)
|
||||||
{
|
{
|
||||||
return AbsoluteTransformation(entity);
|
return glm::translate(AbsolutePosition(entity)) * glm::toMat4(AbsoluteOrientation(entity)) * glm::scale(AbsoluteScale(entity));
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 Transform::TransformPoint(const glm::vec3& point, const glm::mat4& matrix)
|
glm::vec3 Transform::TransformPoint(const glm::vec3& point, const glm::mat4& matrix)
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ bool RenderSystem::isEntityVisible(EntityWrapper& entity)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Hide things parented to local player if they have the HiddenFromLocalPlayer component
|
// Hide things parented to local player if they have the HiddenFromLocalPlayer component
|
||||||
bool outOfBodyExperience = ResourceManager::Load<ConfigFile>("Config.ini")->Get<bool>("Debug.OutOfBodyExperience", false);
|
bool outOfBodyExperience = false; // ResourceManager::Load<ConfigFile>("Config.ini")->Get<bool>("Debug.OutOfBodyExperience", false);
|
||||||
if (
|
if (
|
||||||
(entity.HasComponent("HiddenForLocalPlayer") || entity.FirstParentWithComponent("HiddenForLocalPlayer").Valid())
|
(entity.HasComponent("HiddenForLocalPlayer") || entity.FirstParentWithComponent("HiddenForLocalPlayer").Valid())
|
||||||
&& (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer))
|
&& (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer))
|
||||||
|
|||||||
@@ -240,6 +240,13 @@ void Game::Tick()
|
|||||||
m_RenderFrame->Clear();
|
m_RenderFrame->Clear();
|
||||||
m_EventBroker->Swap();
|
m_EventBroker->Swap();
|
||||||
m_EventBroker->Clear();
|
m_EventBroker->Clear();
|
||||||
|
|
||||||
|
//LOG_DEBUG("Recalculated positions: %i", Transform::RecalculatedPositions);
|
||||||
|
//LOG_DEBUG("Recalculated orientations: %i", Transform::RecalculatedOrientations);
|
||||||
|
//LOG_DEBUG("Recalculated scales: %i", Transform::RecalculatedScales);
|
||||||
|
Transform::RecalculatedPositions = 0;
|
||||||
|
Transform::RecalculatedOrientations = 0;
|
||||||
|
Transform::RecalculatedScales = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Game::parseArgs(int argc, char* argv[])
|
int Game::parseArgs(int argc, char* argv[])
|
||||||
|
|||||||
Reference in New Issue
Block a user