Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Kill rules #975

Merged
merged 1 commit into from
Dec 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Dev/Cpp/Effekseer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ set(effekseer_src
Effekseer/IO/Effekseer.EfkEfcFactory.cpp
Effekseer/Parameter/Easing.cpp
Effekseer/Parameter/Effekseer.Parameters.cpp
Effekseer/Parameter/KillRules.cpp
Effekseer/Parameter/Rotation.cpp
Effekseer/Utils/Effekseer.CustomAllocator.cpp
Effekseer/SIMD/Mat43f.cpp
Expand Down
56 changes: 3 additions & 53 deletions Dev/Cpp/Effekseer/Effekseer/Effekseer.Instance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -503,61 +503,11 @@ void Instance::Update(float deltaFrame, bool shown)
}

// checking kill rules
if (!removed && m_pEffectNode->KillParam.Type != KillType::None)
if (!removed)
{
SIMD::Vec3f localPosition{};
if (m_pEffectNode->KillParam.IsScaleAndRotationApplied)
if (KillRulesParameter::CheckRemoved(m_pEffectNode->KillParam, *GetInstanceGlobal(), prevGlobalPosition_))
{
SIMD::Mat44f invertedGlobalMatrix = this->GetInstanceGlobal()->InvertedEffectGlobalMatrix;
localPosition = SIMD::Vec3f::Transform(this->prevGlobalPosition_, invertedGlobalMatrix);
}
else
{
SIMD::Mat44f globalMatrix = this->GetInstanceGlobal()->EffectGlobalMatrix;
localPosition = this->prevGlobalPosition_ - globalMatrix.GetTranslation();
}

if (m_pEffectNode->KillParam.Type == KillType::Box)
{
localPosition = localPosition - m_pEffectNode->KillParam.Box.Center;
localPosition = SIMD::Vec3f::Abs(localPosition);
SIMD::Vec3f size = m_pEffectNode->KillParam.Box.Size;
bool isWithin = localPosition.GetX() <= size.GetX() && localPosition.GetY() <= size.GetY() && localPosition.GetZ() <= size.GetZ();

if (isWithin && m_pEffectNode->KillParam.Box.IsKillInside > 0)
{
removed = true;
}
else if (!isWithin && m_pEffectNode->KillParam.Box.IsKillInside == 0)
{
removed = true;
}
}
else if (m_pEffectNode->KillParam.Type == KillType::Plane)
{
SIMD::Vec3f planeNormal = m_pEffectNode->KillParam.Plane.PlaneAxis;
SIMD::Vec3f planePosition = planeNormal * m_pEffectNode->KillParam.Plane.PlaneOffset;
float planeW = -SIMD::Vec3f::Dot(planePosition, planeNormal);
float factor = SIMD::Vec3f::Dot(localPosition, planeNormal) + planeW;
if (factor > 0.0F)
{
removed = true;
}
}
else if (m_pEffectNode->KillParam.Type == KillType::Sphere)
{
SIMD::Vec3f delta = localPosition - m_pEffectNode->KillParam.Sphere.Center;
float distance = delta.GetSquaredLength();
float radius = m_pEffectNode->KillParam.Sphere.Radius;
bool isWithin = distance <= (radius * radius);
if (isWithin && m_pEffectNode->KillParam.Sphere.IsKillInside > 0)
{
removed = true;
}
else if (!isWithin && m_pEffectNode->KillParam.Sphere.IsKillInside == 0)
{
removed = true;
}
removed = true;
}
}
}
Expand Down
159 changes: 159 additions & 0 deletions Dev/Cpp/Effekseer/Effekseer/Parameter/KillRules.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
#include "KillRules.h"
#include "../SIMD/Mat44f.h"

namespace Effekseer
{

void KillRulesParameter::Load(unsigned char*& pos, int version)
{
if (version >= Version17Alpha5)
{
memcpy(&Type, pos, sizeof(int32_t));
pos += sizeof(int32_t);

memcpy(&IsScaleAndRotationApplied, pos, sizeof(int));
pos += sizeof(int);

if (Type == KillType::Box)
{
memcpy(&Box.Center, pos, sizeof(Vector3D));
pos += sizeof(Vector3D);

memcpy(&Box.Size, pos, sizeof(Vector3D));
pos += sizeof(Vector3D);

memcpy(&Box.IsKillInside, pos, sizeof(int));
pos += sizeof(int);
}
else if (Type == KillType::Plane)
{
memcpy(&Plane.PlaneAxis, pos, sizeof(Vector3D));
pos += sizeof(Vector3D);

memcpy(&Plane.PlaneOffset, pos, sizeof(float));
pos += sizeof(float);

const auto length = Vector3D::Length(Vector3D{Plane.PlaneAxis.x, Plane.PlaneAxis.y, Plane.PlaneAxis.z});
Plane.PlaneAxis.x /= length;
Plane.PlaneAxis.y /= length;
Plane.PlaneAxis.z /= length;
}
else if (Type == KillType::Sphere)
{
memcpy(&Sphere.Center, pos, sizeof(Vector3D));
pos += sizeof(Vector3D);

memcpy(&Sphere.Radius, pos, sizeof(float));
pos += sizeof(float);

memcpy(&Sphere.IsKillInside, pos, sizeof(int));
pos += sizeof(int);
}
}
else
{
Type = KillType::None;
IsScaleAndRotationApplied = 1;
}
}

void KillRulesParameter::Magnify(float magnification)
{
if (Type == KillType::Box)
{
Box.Center *= magnification;
Box.Size *= magnification;
}
else if (Type == KillType::Plane)
{
Plane.PlaneOffset *= magnification;
}
else if (Type == KillType::Sphere)
{
Sphere.Center *= magnification;
Sphere.Radius *= magnification;
}
}

void KillRulesParameter::MakeCoordinateSystemLH()
{
if (Type == KillType::Box)
{
Box.Center.z *= -1.0F;
}
else if (Type == KillType::Plane)
{
Plane.PlaneAxis.z *= -1.0F;
}
else if (Type == KillType::Sphere)
{
Sphere.Center.z *= -1.0F;
}
}

bool KillRulesParameter::CheckRemoved(const KillRulesParameter& param, const InstanceGlobal& instance_global, const SIMD::Vec3f& prev_global_position)
{
if (param.Type == KillType::None)
{
return false;
}

SIMD::Vec3f localPosition{};
if (param.IsScaleAndRotationApplied)
{
SIMD::Mat44f invertedGlobalMatrix = instance_global.InvertedEffectGlobalMatrix;
localPosition = SIMD::Vec3f::Transform(prev_global_position, invertedGlobalMatrix);
}
else
{
SIMD::Mat44f globalMatrix = instance_global.EffectGlobalMatrix;
localPosition = prev_global_position - globalMatrix.GetTranslation();
}

if (param.Type == KillType::Box)
{
localPosition = localPosition - param.Box.Center;
localPosition = SIMD::Vec3f::Abs(localPosition);
SIMD::Vec3f size = param.Box.Size;
bool isWithin = localPosition.GetX() <= size.GetX() && localPosition.GetY() <= size.GetY() && localPosition.GetZ() <= size.GetZ();

if (isWithin && param.Box.IsKillInside > 0)
{
return true;
}
else if (!isWithin && param.Box.IsKillInside == 0)
{
return true;
}
}
else if (param.Type == KillType::Plane)
{
SIMD::Vec3f planeNormal = param.Plane.PlaneAxis;
SIMD::Vec3f planePosition = planeNormal * param.Plane.PlaneOffset;
float planeW = -SIMD::Vec3f::Dot(planePosition, planeNormal);
float factor = SIMD::Vec3f::Dot(localPosition, planeNormal) + planeW;
if (factor > 0.0F)
{
return true;
}
}
else if (param.Type == KillType::Sphere)
{
SIMD::Vec3f delta = localPosition - param.Sphere.Center;
float distance = delta.GetSquaredLength();
float radius = param.Sphere.Radius;
bool isWithin = distance <= (radius * radius);
if (isWithin && param.Sphere.IsKillInside > 0)
{
return true;
}
else if (!isWithin && param.Sphere.IsKillInside == 0)
{
return true;
}
}

return false;
}

} // namespace Effekseer
91 changes: 7 additions & 84 deletions Dev/Cpp/Effekseer/Effekseer/Parameter/KillRules.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#pragma once

#include "../Effekseer.InstanceGlobal.h"
#include "../Effekseer.InternalStruct.h"
#include "../SIMD/Vec3f.h"
#include "../Utils/BinaryVersion.h"

namespace Effekseer
{
Expand All @@ -15,7 +18,6 @@ enum class KillType : int32_t

struct KillRulesParameter
{

KillType Type = KillType::None;
int IsScaleAndRotationApplied = 1;

Expand All @@ -42,92 +44,13 @@ struct KillRulesParameter
} Sphere;
};

void Load(unsigned char*& pos, int version)
{
if (version >= Version17Alpha5)
{
memcpy(&Type, pos, sizeof(int32_t));
pos += sizeof(int32_t);

memcpy(&IsScaleAndRotationApplied, pos, sizeof(int));
pos += sizeof(int);

if (Type == KillType::Box)
{
memcpy(&Box.Center, pos, sizeof(Vector3D));
pos += sizeof(Vector3D);
void Load(unsigned char*& pos, int version);

memcpy(&Box.Size, pos, sizeof(Vector3D));
pos += sizeof(Vector3D);
void Magnify(float magnification);

memcpy(&Box.IsKillInside, pos, sizeof(int));
pos += sizeof(int);
}
else if (Type == KillType::Plane)
{
memcpy(&Plane.PlaneAxis, pos, sizeof(Vector3D));
pos += sizeof(Vector3D);

memcpy(&Plane.PlaneOffset, pos, sizeof(float));
pos += sizeof(float);

const auto length = Vector3D::Length(Vector3D{Plane.PlaneAxis.x, Plane.PlaneAxis.y, Plane.PlaneAxis.z});
Plane.PlaneAxis.x /= length;
Plane.PlaneAxis.y /= length;
Plane.PlaneAxis.z /= length;
}
else if (Type == KillType::Sphere)
{
memcpy(&Sphere.Center, pos, sizeof(Vector3D));
pos += sizeof(Vector3D);

memcpy(&Sphere.Radius, pos, sizeof(float));
pos += sizeof(float);

memcpy(&Sphere.IsKillInside, pos, sizeof(int));
pos += sizeof(int);
}
}
else
{
Type = KillType::None;
IsScaleAndRotationApplied = 1;
}
}
void MakeCoordinateSystemLH();

void Magnify(float magnification)
{
if (Type == KillType::Box)
{
Box.Center *= magnification;
Box.Size *= magnification;
}
else if (Type == KillType::Plane)
{
Plane.PlaneOffset *= magnification;
}
else if (Type == KillType::Sphere)
{
Sphere.Center *= magnification;
Sphere.Radius *= magnification;
}
}

void MakeCoordinateSystemLH()
{
if (Type == KillType::Box)
{
Box.Center.z *= -1.0F;
}
else if (Type == KillType::Plane)
{
Plane.PlaneAxis.z *= -1.0F;
}
else if (Type == KillType::Sphere)
{
Sphere.Center.z *= -1.0F;
}
}
static bool CheckRemoved(const KillRulesParameter& param, const InstanceGlobal& instance_global, const SIMD::Vec3f& prev_global_position);
};

} // namespace Effekseer
Loading