目录
前言
本节内容用于transform功能的实现
一、主要工作
渲染器包括了基础的模型信息系统,因此图形学中关键的坐标系变化相关的功能是必要的。本节主要讲解平移、旋转、缩放的相关函数与数据结构的实现。
二、具体代码
1、头文件包含了transform类,包括translate、scale、rotate等,并且编写了将欧拉角转化为四元数的功能,此外还包括了基础的lookat视锥体变化函数。
class FALCOR_API Transform
{
public:
Transform();
const float3& getTranslation() const { return mTranslation; }
void setTranslation(const float3& translation);
const float3& getScaling() const { return mScaling; }
void setScaling(const float3& scaling);
const glm::quat& getRotation() const { return mRotation; }
void setRotation(const glm::quat& rotation);
float3 getRotationEuler() const;
void setRotationEuler(const float3& angles);
float3 getRotationEulerDeg() const;
void setRotationEulerDeg(const float3& angles);
void lookAt(const float3& position, const float3& target, const float3& up);
const glm::float4x4& getMatrix() const;
bool operator==(const Transform& other) const;
bool operator!=(const Transform& other) const { return !((*this) == other); }
private:
float3 mTranslation = float3(0.f);
float3 mScaling = float3(1.f);
glm::quat mRotation = glm::identity<glm::quat>();
mutable bool mDirty = true;
mutable glm::float4x4 mMatrix;
friend class SceneCache;
};
2、函数体的内容如下
Transform::Transform() {}
void Transform::setTranslation(const float3& translation)
{
mTranslation = translation;
mDirty = true;
}
void Transform::setScaling(const float3& scaling)
{
mScaling = scaling;
mDirty = true;
}
void Transform::setRotation(const glm::quat& rotation)
{
mRotation = rotation;
mDirty = true;
}
float3 Transform::getRotationEuler() const
{
return glm::eulerAngles(mRotation);
}
void Transform::setRotationEuler(const float3& angles)
{
setRotation(glm::quat(angles));
}
float3 Transform::getRotationEulerDeg() const
{
return glm::degrees(getRotationEuler());
}
void Transform::setRotationEulerDeg(const float3& angles)
{
setRotationEuler(glm::radians(angles));
}
void Transform::lookAt(const float3& position, const float3& target, const float3& up)
{
mTranslation = position;
float3 dir = normalize(target - position);
mRotation = glm::quatLookAt(dir, up);
}
const glm::float4x4& Transform::getMatrix() const
{
if (mDirty)
{
glm::mat4 T = translate(mTranslation);
glm::mat4 R = mat4_cast(mRotation);
glm::mat4 S = scale(mScaling);
mMatrix = T * R * S;
mDirty = false;
}
return mMatrix;
}
bool Transform::operator==(const Transform& other) const
{
if (mTranslation != other.mTranslation) return false;
if (mScaling != other.mScaling) return false;
if (mRotation != other.mRotation) return false;
return true;
}
FALCOR_SCRIPT_BINDING(Transform)
{
auto init = [](const pybind11::kwargs& args)
{
Transform transform;
std::optional<float3> position;
std::optional<float3> target;
std::optional<float3> up;
for (auto a : args)
{
auto key = a.first.cast<std::string>();
const auto& value = a.second;
float3 float3Value;
float floatValue;
bool isFloat3 = pybind11::isinstance<float3>(value);
bool isNumber = pybind11::isinstance<pybind11::int_>(value) || pybind11::isinstance<pybind11::float_>(value);
if (isFloat3) float3Value = pybind11::cast<float3>(value);
if (isNumber) floatValue = pybind11::cast<float>(value);
if (key == "translation")
{
if (isFloat3) transform.setTranslation(float3Value);
}
else if (key == "scaling")
{
if (isFloat3) transform.setScaling(float3Value);
if (isNumber) transform.setScaling(float3(floatValue));
}
else if (key == "rotationEuler")
{
if (isFloat3) transform.setRotationEuler(float3Value);
}
else if (key == "rotationEulerDeg")
{
if (isFloat3) transform.setRotationEulerDeg(float3Value);
}
else if (key == "position")
{
if (isFloat3) position = float3Value;
}
else if (key == "target")
{
if (isFloat3) target = float3Value;
}
else if (key == "up")
{
if (isFloat3) up = float3Value;
}
}
if (position && target && up)
{
transform.lookAt(*position, *target, *up);
}
return transform;
};
pybind11::class_<Transform> transform(m, "Transform");
transform.def(pybind11::init(init));
transform.def_property("translation", &Transform::getTranslation, &Transform::setTranslation);
transform.def_property("rotationEuler", &Transform::getRotationEuler, &Transform::setRotationEuler);
transform.def_property("rotationEulerDeg", &Transform::getRotationEulerDeg, &Transform::setRotationEulerDeg);
transform.def_property("scaling", &Transform::getScaling, &Transform::setScaling);
transform.def_property_readonly("matrix", &Transform::getMatrix);
transform.def("lookAt", &Transform::lookAt, "position"_a, "target"_a, "up"_a);
}
以上就是本节的全部内容