first commit
This commit is contained in:
310
ios/include/filament/TransformManager.h
Normal file
310
ios/include/filament/TransformManager.h
Normal file
@@ -0,0 +1,310 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_FILAMENT_TRANSFORMMANAGER_H
|
||||
#define TNT_FILAMENT_TRANSFORMMANAGER_H
|
||||
|
||||
#include <filament/FilamentAPI.h>
|
||||
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/EntityInstance.h>
|
||||
|
||||
#include <math/mathfwd.h>
|
||||
|
||||
#include <iterator>
|
||||
|
||||
|
||||
namespace utils {
|
||||
class Entity;
|
||||
} // namespace utils
|
||||
|
||||
namespace filament {
|
||||
|
||||
class FTransformManager;
|
||||
|
||||
/**
|
||||
* TransformManager is used to add transform components to entities.
|
||||
*
|
||||
* A Transform component gives an entity a position and orientation in space in the coordinate
|
||||
* space of its parent transform. The TransformManager takes care of computing the world-space
|
||||
* transform of each component (i.e. its transform relative to the root).
|
||||
*
|
||||
* Creation and destruction
|
||||
* ========================
|
||||
*
|
||||
* A transform component is created using TransformManager::create() and destroyed by calling
|
||||
* TransformManager::destroy().
|
||||
*
|
||||
* ~~~~~~~~~~~{.cpp}
|
||||
* filament::Engine* engine = filament::Engine::create();
|
||||
* utils::Entity object = utils::EntityManager.get().create();
|
||||
*
|
||||
* auto& tcm = engine->getTransformManager();
|
||||
*
|
||||
* // create the transform component
|
||||
* tcm.create(object);
|
||||
*
|
||||
* // set its transform
|
||||
* auto i = tcm.getInstance(object);
|
||||
* tcm.setTransform(i, mat4f::translation({ 0, 0, -1 }));
|
||||
*
|
||||
* // destroy the transform component
|
||||
* tcm.destroy(object);
|
||||
* ~~~~~~~~~~~
|
||||
*
|
||||
*/
|
||||
class UTILS_PUBLIC TransformManager : public FilamentAPI {
|
||||
public:
|
||||
using Instance = utils::EntityInstance<TransformManager>;
|
||||
|
||||
class children_iterator : std::iterator<std::forward_iterator_tag, Instance> {
|
||||
friend class FTransformManager;
|
||||
TransformManager const& mManager;
|
||||
Instance mInstance;
|
||||
children_iterator(TransformManager const& mgr, Instance instance) noexcept
|
||||
: mManager(mgr), mInstance(instance) { }
|
||||
public:
|
||||
children_iterator& operator++();
|
||||
|
||||
children_iterator operator++(int) { // NOLINT
|
||||
children_iterator ret(*this);
|
||||
++(*this);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool operator == (const children_iterator& other) const noexcept {
|
||||
return mInstance == other.mInstance;
|
||||
}
|
||||
|
||||
bool operator != (const children_iterator& other) const noexcept {
|
||||
return mInstance != other.mInstance;
|
||||
}
|
||||
|
||||
value_type operator*() const { return mInstance; }
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns whether a particular Entity is associated with a component of this TransformManager
|
||||
* @param e An Entity.
|
||||
* @return true if this Entity has a component associated with this manager.
|
||||
*/
|
||||
bool hasComponent(utils::Entity e) const noexcept;
|
||||
|
||||
/**
|
||||
* Gets an Instance representing the transform component associated with the given Entity.
|
||||
* @param e An Entity.
|
||||
* @return An Instance object, which represents the transform component associated with the Entity e.
|
||||
* @note Use Instance::isValid() to make sure the component exists.
|
||||
* @see hasComponent()
|
||||
*/
|
||||
Instance getInstance(utils::Entity e) const noexcept;
|
||||
|
||||
/**
|
||||
* Enables or disable the accurate translation mode. Disabled by default.
|
||||
*
|
||||
* When accurate translation mode is active, the translation component of all transforms is
|
||||
* maintained at double precision. This is only useful if the mat4 version of setTransform()
|
||||
* is used, as well as getTransformAccurate().
|
||||
*
|
||||
* @param enable true to enable the accurate translation mode, false to disable.
|
||||
*
|
||||
* @see isAccurateTranslationsEnabled
|
||||
* @see create(utils::Entity, Instance, const math::mat4&);
|
||||
* @see setTransform(Instance, const math::mat4&)
|
||||
* @see getTransformAccurate
|
||||
* @see getWorldTransformAccurate
|
||||
*/
|
||||
void setAccurateTranslationsEnabled(bool enable) noexcept;
|
||||
|
||||
/**
|
||||
* Returns whether the high precision translation mode is active.
|
||||
* @return true if accurate translations mode is active, false otherwise
|
||||
* @see setAccurateTranslationsEnabled
|
||||
*/
|
||||
bool isAccurateTranslationsEnabled() const noexcept;
|
||||
|
||||
/**
|
||||
* Creates a transform component and associate it with the given entity.
|
||||
* @param entity An Entity to associate a transform component to.
|
||||
* @param parent The Instance of the parent transform, or Instance{} if no parent.
|
||||
* @param localTransform The transform to initialize the transform component with.
|
||||
* This is always relative to the parent.
|
||||
*
|
||||
* If this component already exists on the given entity, it is first destroyed as if
|
||||
* destroy(utils::Entity e) was called.
|
||||
*
|
||||
* @see destroy()
|
||||
*/
|
||||
void create(utils::Entity entity, Instance parent, const math::mat4f& localTransform);
|
||||
void create(utils::Entity entity, Instance parent, const math::mat4& localTransform); //!< \overload
|
||||
void create(utils::Entity entity, Instance parent = {}); //!< \overload
|
||||
|
||||
/**
|
||||
* Destroys this component from the given entity, children are orphaned.
|
||||
* @param e An entity.
|
||||
*
|
||||
* @note If this transform had children, these are orphaned, which means their local
|
||||
* transform becomes a world transform. Usually it's nonsensical. It's recommended to make
|
||||
* sure that a destroyed transform doesn't have children.
|
||||
*
|
||||
* @see create()
|
||||
*/
|
||||
void destroy(utils::Entity e) noexcept;
|
||||
|
||||
/**
|
||||
* Re-parents an entity to a new one.
|
||||
* @param i The instance of the transform component to re-parent
|
||||
* @param newParent The instance of the new parent transform
|
||||
* @attention It is an error to re-parent an entity to a descendant and will cause undefined behaviour.
|
||||
* @see getInstance()
|
||||
*/
|
||||
void setParent(Instance i, Instance newParent) noexcept;
|
||||
|
||||
/**
|
||||
* Returns the parent of a transform component, or the null entity if it is a root.
|
||||
* @param i The instance of the transform component to query.
|
||||
*/
|
||||
utils::Entity getParent(Instance i) const noexcept;
|
||||
|
||||
/**
|
||||
* Returns the number of children of a transform component.
|
||||
* @param i The instance of the transform component to query.
|
||||
* @return The number of children of the queried component.
|
||||
*/
|
||||
size_t getChildCount(Instance i) const noexcept;
|
||||
|
||||
/**
|
||||
* Gets a list of children for a transform component.
|
||||
*
|
||||
* @param i The instance of the transform component to query.
|
||||
* @param children Pointer to array-of-Entity. The array must have at least "count" elements.
|
||||
* @param count The maximum number of children to retrieve.
|
||||
* @return The number of children written to the pointer.
|
||||
*/
|
||||
size_t getChildren(Instance i, utils::Entity* children, size_t count) const noexcept;
|
||||
|
||||
/**
|
||||
* Returns an iterator to the Instance of the first child of the given parent.
|
||||
*
|
||||
* @param parent Instance of the parent
|
||||
* @return A forward iterator pointing to the first child of the given parent.
|
||||
*
|
||||
* A child_iterator can only safely be dereferenced if it's different from getChildrenEnd(parent)
|
||||
*/
|
||||
children_iterator getChildrenBegin(Instance parent) const noexcept;
|
||||
|
||||
/**
|
||||
* Returns an undreferencable iterator representing the end of the children list
|
||||
*
|
||||
* @param parent Instance of the parent
|
||||
* @return A forward iterator.
|
||||
*
|
||||
* This iterator cannot be dereferenced
|
||||
*/
|
||||
children_iterator getChildrenEnd(Instance parent) const noexcept;
|
||||
|
||||
/**
|
||||
* Sets a local transform of a transform component.
|
||||
* @param ci The instance of the transform component to set the local transform to.
|
||||
* @param localTransform The local transform (i.e. relative to the parent).
|
||||
* @see getTransform()
|
||||
* @attention This operation can be slow if the hierarchy of transform is too deep, and this
|
||||
* will be particularly bad when updating a lot of transforms. In that case,
|
||||
* consider using openLocalTransformTransaction() / commitLocalTransformTransaction().
|
||||
*/
|
||||
void setTransform(Instance ci, const math::mat4f& localTransform) noexcept;
|
||||
|
||||
/**
|
||||
* Sets a local transform of a transform component and keeps double precision translation.
|
||||
* All other values of the transform are stored at single precision.
|
||||
* @param ci The instance of the transform component to set the local transform to.
|
||||
* @param localTransform The local transform (i.e. relative to the parent).
|
||||
* @see getTransform()
|
||||
* @attention This operation can be slow if the hierarchy of transform is too deep, and this
|
||||
* will be particularly bad when updating a lot of transforms. In that case,
|
||||
* consider using openLocalTransformTransaction() / commitLocalTransformTransaction().
|
||||
*/
|
||||
void setTransform(Instance ci, const math::mat4& localTransform) noexcept;
|
||||
|
||||
/**
|
||||
* Returns the local transform of a transform component.
|
||||
* @param ci The instance of the transform component to query the local transform from.
|
||||
* @return The local transform of the component (i.e. relative to the parent). This always
|
||||
* returns the value set by setTransform().
|
||||
* @see setTransform()
|
||||
*/
|
||||
const math::mat4f& getTransform(Instance ci) const noexcept;
|
||||
|
||||
/**
|
||||
* Returns the local transform of a transform component.
|
||||
* @param ci The instance of the transform component to query the local transform from.
|
||||
* @return The local transform of the component (i.e. relative to the parent). This always
|
||||
* returns the value set by setTransform().
|
||||
* @see setTransform()
|
||||
*/
|
||||
const math::mat4 getTransformAccurate(Instance ci) const noexcept;
|
||||
|
||||
/**
|
||||
* Return the world transform of a transform component.
|
||||
* @param ci The instance of the transform component to query the world transform from.
|
||||
* @return The world transform of the component (i.e. relative to the root). This is the
|
||||
* composition of this component's local transform with its parent's world transform.
|
||||
* @see setTransform()
|
||||
*/
|
||||
const math::mat4f& getWorldTransform(Instance ci) const noexcept;
|
||||
|
||||
/**
|
||||
* Return the world transform of a transform component.
|
||||
* @param ci The instance of the transform component to query the world transform from.
|
||||
* @return The world transform of the component (i.e. relative to the root). This is the
|
||||
* composition of this component's local transform with its parent's world transform.
|
||||
* @see setTransform()
|
||||
*/
|
||||
const math::mat4 getWorldTransformAccurate(Instance ci) const noexcept;
|
||||
|
||||
/**
|
||||
* Opens a local transform transaction. During a transaction, getWorldTransform() can
|
||||
* return an invalid transform until commitLocalTransformTransaction() is called. However,
|
||||
* setTransform() will perform significantly better and in constant time.
|
||||
*
|
||||
* This is useful when updating many transforms and the transform hierarchy is deep (say more
|
||||
* than 4 or 5 levels).
|
||||
*
|
||||
* @note If the local transform transaction is already open, this is a no-op.
|
||||
*
|
||||
* @see commitLocalTransformTransaction(), setTransform()
|
||||
*/
|
||||
void openLocalTransformTransaction() noexcept;
|
||||
|
||||
/**
|
||||
* Commits the currently open local transform transaction. When this returns, calls
|
||||
* to getWorldTransform() will return the proper value.
|
||||
*
|
||||
* @attention failing to call this method when done updating the local transform will cause
|
||||
* a lot of rendering problems. The system never closes the transaction
|
||||
* automatically.
|
||||
*
|
||||
* @note If the local transform transaction is not open, this is a no-op.
|
||||
*
|
||||
* @see openLocalTransformTransaction(), setTransform()
|
||||
*/
|
||||
void commitLocalTransformTransaction() noexcept;
|
||||
};
|
||||
|
||||
} // namespace filament
|
||||
|
||||
|
||||
#endif // TNT_TRANSFORMMANAGER_H
|
||||
Reference in New Issue
Block a user