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

Make a velocity saved in a particle instance #957

Merged
merged 5 commits into from
Sep 27, 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
48 changes: 36 additions & 12 deletions Dev/Cpp/Effekseer/Effekseer/Effekseer.Instance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,9 @@ void Instance::Initialize(Instance* parent, float spawnDeltaFrame, int32_t insta
m_randObject.SetSeed(instanceGlobal->GetRandObject().GetRandInt());

prevPosition_ = SIMD::Vec3f(0, 0, 0);
prevLocalVelocity_ = SIMD::Vec3f(0, 0, 0);
location_modify_global_ = SIMD::Vec3f(0, 0, 0);
velocity_modify_global_ = SIMD::Vec3f(0, 0, 0);
}

void Instance::FirstUpdate()
Expand Down Expand Up @@ -375,6 +378,7 @@ void Instance::FirstUpdate()
}

prevGlobalPosition_ = SIMD::Vec3f::Transform(prevPosition_, m_ParentMatrix);
prevLocalVelocity_ = SIMD::Vec3f(0, 0, 0);

m_pEffectNode->InitializeRenderedInstance(*this, *ownGroup_, m_pManager);
}
Expand Down Expand Up @@ -637,8 +641,17 @@ void Instance::UpdateTransform(float deltaFrame)
UpdateParentMatrix(deltaFrame);
}

float accerarationDelta = deltaFrame;
if (deltaFrame > 1)
{
// trapezoid interporation
accerarationDelta = ((1.0f + 1.0f / deltaFrame) / 2.0f) * deltaFrame;
}

SIMD::Vec3f localPosition = prevPosition_;
SIMD::Vec3f localVelocity;
SIMD::Vec3f localVelocity = prevLocalVelocity_;

SIMD::Vec3f localAcc = SIMD::Vec3f(0, 0, 0);

if (m_pEffectNode->CommonValues.TranslationBindType == TranslationParentBindType::NotBind_FollowParent ||
m_pEffectNode->CommonValues.TranslationBindType == TranslationParentBindType::WhenCreating_FollowParent)
Expand All @@ -652,6 +665,7 @@ void Instance::UpdateTransform(float deltaFrame)
toTarget *= followParentParam.maxFollowSpeed;
}

auto prevSteering = steeringVec_;
SIMD::Vec3f vSteering = toTarget - steeringVec_;
vSteering *= followParentParam.steeringSpeed;

Expand All @@ -663,34 +677,42 @@ void Instance::UpdateTransform(float deltaFrame)
steeringVec_ *= followParentParam.maxFollowSpeed;
}

localVelocity = steeringVec_ * deltaFrame * m_pEffectNode->m_effect->GetMaginification();
localAcc = (steeringVec_ - prevSteering) * m_pEffectNode->m_effect->GetMaginification();
}
else
{
localVelocity = m_pEffectNode->TranslationParam.CalculateTranslationState(translation_values, m_randObject, m_pEffectNode->GetEffect(), m_pContainer->GetRootInstance(), m_LivingTime, m_LivedTime, m_pParent, coordinateSystem, m_pEffectNode->DynamicFactor);
localAcc = m_pEffectNode->TranslationParam.CalculateTranslationState(translation_values, m_randObject, m_pEffectNode->GetEffect(), m_pContainer->GetRootInstance(), m_LivingTime, m_LivedTime, deltaFrame, m_pParent, coordinateSystem, m_pEffectNode->DynamicFactor);

if (m_pEffectNode->GenerationLocation.EffectsRotation)
{
// TODO : check rotation(It seems has bugs and it can optimize it)
localVelocity = SIMD::Vec3f::Transform(localVelocity, m_GenerationLocation.Get3x3SubMatrix());
localAcc = SIMD::Vec3f::Transform(localAcc, m_GenerationLocation.Get3x3SubMatrix());
}
}

localPosition += localVelocity;

auto matRot = RotationFunctions::CalculateRotation(rotation_values, m_pEffectNode->RotationParam, m_randObject, m_pEffectNode->GetEffect(), m_pContainer->GetRootInstance(), m_LivingTime, m_LivedTime, m_pParent, m_pEffectNode->DynamicFactor, m_pManager->GetLayerParameter(GetInstanceGlobal()->GetLayer()).ViewerPosition);
auto scaling = ScalingFunctions::UpdateScaling(scaling_values, m_pEffectNode->ScalingParam, m_randObject, m_pEffectNode->GetEffect(), m_pContainer->GetRootInstance(), m_LivingTime, m_LivedTime, m_pParent, m_pEffectNode->DynamicFactor);

// update local fields
if (m_pEffectNode->LocalForceField.HasValue)
{
forceField_.ExternalVelocity = localVelocity;
localPosition += forceField_.Update(m_pEffectNode->LocalForceField, localPosition, m_pEffectNode->GetEffect()->GetMaginification(), deltaFrame, m_pEffectNode->GetEffect()->GetSetting()->GetCoordinateSystem());
// for compatibiliy
auto new_local_position = localPosition + (localVelocity * deltaFrame + localAcc * accerarationDelta);

localAcc += forceField_.Update(
m_pEffectNode->LocalForceField,
new_local_position,
localVelocity,
m_pEffectNode->GetEffect()->GetMaginification(),
deltaFrame,
m_pEffectNode->GetEffect()->GetSetting()->GetCoordinateSystem());
}

localPosition += localVelocity * deltaFrame + localAcc * accerarationDelta;
localVelocity += localAcc;
prevPosition_ = localPosition;
prevLocalVelocity_ = localVelocity;

/* 描画部分の更新 */
m_pEffectNode->UpdateRenderedInstance(*this, *ownGroup_, m_pManager);

// Update matrix
Expand All @@ -716,9 +738,11 @@ void Instance::UpdateTransform(float deltaFrame)
if (m_pEffectNode->LocalForceField.IsGlobalEnabled)
{
InstanceGlobal* instanceGlobal = m_pContainer->GetRootInstance();
forceField_.UpdateGlobal(m_pEffectNode->LocalForceField, prevGlobalPosition_, m_pEffectNode->GetEffect()->GetMaginification(), instanceGlobal->GetTargetLocation(), deltaFrame, m_pEffectNode->GetEffect()->GetSetting()->GetCoordinateSystem());
SIMD::Mat43f MatTraGlobal = SIMD::Mat43f::Translation(forceField_.GlobalModifyLocation);
calcMat *= MatTraGlobal;
const auto acc_global = forceField_.UpdateGlobal(m_pEffectNode->LocalForceField, prevGlobalPosition_, m_pEffectNode->GetEffect()->GetMaginification(), instanceGlobal->GetTargetLocation(), deltaFrame, m_pEffectNode->GetEffect()->GetSetting()->GetCoordinateSystem());
location_modify_global_ += velocity_modify_global_ * deltaFrame + acc_global * accerarationDelta;
velocity_modify_global_ += acc_global;
SIMD::Mat43f mat_location_global = SIMD::Mat43f::Translation(location_modify_global_);
calcMat *= mat_location_global;
}

globalMatrix_.Step(calcMat, m_LivingTime);
Expand Down
6 changes: 6 additions & 0 deletions Dev/Cpp/Effekseer/Effekseer/Effekseer.Instance.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,15 @@ class alignas(16) Instance : public IntrusiveList<Instance>::Node
SIMD::Vec3f prevPosition_;
SIMD::Vec3f prevGlobalPosition_;

SIMD::Vec3f prevLocalVelocity_;

SIMD::Vec3f parentPosition_;

SIMD::Vec3f steeringVec_;

SIMD::Vec3f location_modify_global_;
SIMD::Vec3f velocity_modify_global_;

public:
static const int32_t ChildrenMax = 16;

Expand Down
45 changes: 27 additions & 18 deletions Dev/Cpp/Effekseer/Effekseer/ForceField/ForceFields.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -355,13 +355,16 @@ void LocalForceFieldParameter::MaintainAttractiveForceCompatibility(const float
LocalForceFields[3].IsGlobal = true;
}

SIMD::Vec3f LocalForceFieldInstance::Update(const LocalForceFieldParameter& parameter, const SIMD::Vec3f& location, float magnification, float deltaFrame, CoordinateSystem coordinateSystem)
SIMD::Vec3f LocalForceFieldInstance::Update(const LocalForceFieldParameter& parameter, const SIMD::Vec3f& location, const SIMD::Vec3f& local_velocity_per_update, float magnification, float deltaFrame, CoordinateSystem coordinateSystem)
{
if (deltaFrame == 0.0f)
{
return SIMD::Vec3f{0, 0, 0};
}

std::array<SIMD::Vec3f, LocalFieldSlotMax> accs;
accs.fill(SIMD::Vec3f(0, 0, 0));

for (size_t i = 0; i < parameter.LocalForceFields.size(); i++)
{
auto& field = parameter.LocalForceFields[i];
Expand All @@ -376,7 +379,7 @@ SIMD::Vec3f LocalForceFieldInstance::Update(const LocalForceFieldParameter& para
ForceFieldCommonParameter ffcp;
ffcp.FieldCenter = parameter.LocalForceFields[i].Position;
ffcp.Position = location / magnification;
ffcp.PreviousSumVelocity = (VelocitySum + ExternalVelocity / deltaFrame) / magnification;
ffcp.PreviousSumVelocity = local_velocity_per_update / magnification;
ffcp.PreviousVelocity = Velocities[i] / magnification;
ffcp.DeltaFrame = deltaFrame;
ffcp.IsFieldRotated = field.IsRotated;
Expand Down Expand Up @@ -455,26 +458,37 @@ SIMD::Vec3f LocalForceFieldInstance::Update(const LocalForceFieldParameter& para
}

Velocities[i] += acc;
accs[i] = acc;
}

VelocitySum = SIMD::Vec3f(0, 0, 0);
SIMD::Vec3f acc_sum = SIMD::Vec3f(0, 0, 0);

for (size_t i = 0; i < parameter.LocalForceFields.size(); i++)
{
if (parameter.LocalForceFields[i].IsGlobal)
continue;

VelocitySum += Velocities[i];
acc_sum += accs[i];
}

return VelocitySum * deltaFrame;
return acc_sum;
}

void LocalForceFieldInstance::UpdateGlobal(const LocalForceFieldParameter& parameter, const SIMD::Vec3f& location, float magnification, const SIMD::Vec3f& targetPosition, float deltaFrame, CoordinateSystem coordinateSystem)
SIMD::Vec3f LocalForceFieldInstance::UpdateGlobal(const LocalForceFieldParameter& parameter, const SIMD::Vec3f& location, float magnification, const SIMD::Vec3f& targetPosition, float deltaFrame, CoordinateSystem coordinateSystem)
{
if (deltaFrame == 0.0f)
{
return;
return SIMD::Vec3f(0, 0, 0);
}

std::array<SIMD::Vec3f, LocalFieldSlotMax> accs;
accs.fill(SIMD::Vec3f(0, 0, 0));

SIMD::Vec3f velocity_sum_prev = SIMD::Vec3f(0, 0, 0);
for (size_t i = 0; i < parameter.LocalForceFields.size(); i++)
{
if (!parameter.LocalForceFields[i].IsGlobal)
continue;
velocity_sum_prev += Velocities[i];
}

for (size_t i = 0; i < parameter.LocalForceFields.size(); i++)
Expand All @@ -491,7 +505,7 @@ void LocalForceFieldInstance::UpdateGlobal(const LocalForceFieldParameter& param
ForceFieldCommonParameter ffcp;
ffcp.FieldCenter = parameter.LocalForceFields[i].Position;
ffcp.Position = location / magnification;
ffcp.PreviousSumVelocity = GlobalVelocitySum / magnification;
ffcp.PreviousSumVelocity = velocity_sum_prev / magnification;
ffcp.PreviousVelocity = Velocities[i] / magnification;
ffcp.TargetPosition = targetPosition / magnification;
ffcp.DeltaFrame = deltaFrame;
Expand Down Expand Up @@ -558,28 +572,23 @@ void LocalForceFieldInstance::UpdateGlobal(const LocalForceFieldParameter& param
}

Velocities[i] += acc;
accs[i] = acc;
}

GlobalVelocitySum = SIMD::Vec3f(0, 0, 0);

SIMD::Vec3f acc_sum = SIMD::Vec3f(0, 0, 0);
for (size_t i = 0; i < parameter.LocalForceFields.size(); i++)
{
if (!parameter.LocalForceFields[i].IsGlobal)
continue;

GlobalVelocitySum += Velocities[i];
acc_sum += accs[i];
}

GlobalModifyLocation += GlobalVelocitySum * deltaFrame;
return acc_sum;
}

void LocalForceFieldInstance::Reset()
{
Velocities.fill(SIMD::Vec3f(0, 0, 0));
VelocitySum = SIMD::Vec3f(0, 0, 0);
GlobalVelocitySum = SIMD::Vec3f(0, 0, 0);
GlobalModifyLocation = SIMD::Vec3f(0, 0, 0);
ExternalVelocity = SIMD::Vec3f(0, 0, 0);
}

} // namespace Effekseer
32 changes: 17 additions & 15 deletions Dev/Cpp/Effekseer/Effekseer/ForceField/ForceFields.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ class ForceField

if (ffp.Gravitation)
{
return dir * ffp.Power / distance;
return dir * ffp.Power / distance * ffc.DeltaFrame;
}

return dir * ffp.Power * ffc.DeltaFrame;
Expand Down Expand Up @@ -289,7 +289,7 @@ class ForceField

auto xlen = power / distance * (power / 2.0f);
auto flen = sqrt(power * power - xlen * xlen);
return ((front * flen - localPos * xlen) * direction - ffc.PreviousVelocity) * ffc.DeltaFrame;
return ((front * flen - localPos * xlen) * direction * ffc.DeltaFrame - ffc.PreviousVelocity);
}

/**
Expand Down Expand Up @@ -353,13 +353,21 @@ class ForceField
if (ffc.DeltaFrame > 0)
{
float eps = 0.0001f;
auto ret = SIMD::Vec3f(0.0f, 0.0f, 0.0f);
auto vel = ffc.PreviousVelocity;
vel += targetDirection * force * ffc.DeltaFrame;
float currentVelocity = vel.GetLength() + eps;
SIMD::Vec3f currentDirection = vel / currentVelocity;
auto deltaFrame = ffc.DeltaFrame;

while (deltaFrame > eps)
{
auto tempDeltaFrame = std::min(1.0f, deltaFrame);
vel += targetDirection * force * tempDeltaFrame;
float currentVelocity = vel.GetLength() + eps;
SIMD::Vec3f currentDirection = vel / currentVelocity;

vel = (targetDirection * ffp.Control + currentDirection * (1.0f - ffp.Control)) * currentVelocity;

deltaFrame -= tempDeltaFrame;
}

vel = (targetDirection * ffp.Control + currentDirection * (1.0f - ffp.Control)) * currentVelocity;
return vel - ffc.PreviousVelocity;
}
}
Expand Down Expand Up @@ -433,15 +441,9 @@ struct LocalForceFieldInstance
{
std::array<SIMD::Vec3f, LocalFieldSlotMax> Velocities;

SIMD::Vec3f ExternalVelocity;
SIMD::Vec3f VelocitySum;

SIMD::Vec3f GlobalVelocitySum;
SIMD::Vec3f GlobalModifyLocation;

SIMD::Vec3f Update(const LocalForceFieldParameter& parameter, const SIMD::Vec3f& location, float magnification, float deltaFrame, CoordinateSystem coordinateSystem);
SIMD::Vec3f Update(const LocalForceFieldParameter& parameter, const SIMD::Vec3f& location, const SIMD::Vec3f& local_velocity_per_update, float magnification, float deltaFrame, CoordinateSystem coordinateSystem);

void UpdateGlobal(const LocalForceFieldParameter& parameter, const SIMD::Vec3f& location, float magnification, const SIMD::Vec3f& targetPosition, float deltaTime, CoordinateSystem coordinateSystem);
SIMD::Vec3f UpdateGlobal(const LocalForceFieldParameter& parameter, const SIMD::Vec3f& location, float magnification, const SIMD::Vec3f& targetPosition, float deltaTime, CoordinateSystem coordinateSystem);

void Reset();
};
Expand Down
14 changes: 12 additions & 2 deletions Dev/Cpp/Effekseer/Effekseer/Parameter/Translation.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ struct InstanceTranslationState
};

SIMD::Vec3f prevLocation;
SIMD::Vec3f prevVelocity;
};

class TranslationParameter
Expand Down Expand Up @@ -383,6 +384,7 @@ class TranslationParameter
}

instanceState.prevLocation = position;
instanceState.prevVelocity = SIMD::Vec3f(0, 0, 0);
}

SIMD::Vec3f CalculateTranslationState(
Expand All @@ -392,10 +394,16 @@ class TranslationParameter
const InstanceGlobal* instanceGlobal,
float livingTime,
float livedTime,
float deltaFrame,
const Instance* m_pParent,
CoordinateSystem coordinateSystem,
const DynamicFactorParameter& dynamicFactor)
{
if (deltaFrame == 0.0f)
{
return SIMD::Vec3f(0, 0, 0);
}

SIMD::Vec3f localPosition;

if (TranslationType == ParameterTranslationType_None)
Expand Down Expand Up @@ -469,9 +477,11 @@ class TranslationParameter
return {0, 0, 0};
}

const auto vel = localPosition - instanceState.prevLocation;
const auto vel = (localPosition - instanceState.prevLocation) / deltaFrame;
const auto acc = vel - instanceState.prevVelocity;
instanceState.prevLocation = localPosition;
return vel;
instanceState.prevVelocity = vel;
return acc;
}
};

Expand Down
2 changes: 1 addition & 1 deletion TestData
Submodule TestData updated 41 files
+ Tests/WebGL/AlphaBlendTexture01.efkefc_step0.png
+ Tests/WebGL/AlphaCutoffEdgeColor01.efkefc_step0.png
+ Tests/WebGL/AlphaCutoffParameter01.efkefc_step0.png
+ Tests/WebGL/BasicRenderSettings_Blend.efkefc_step0.png
+ Tests/WebGL/BasicRenderSettings_Inherit_Color.efkefc_step0.png
+ Tests/WebGL/EdgeFallOff01.efkefc_step0.png
+ Tests/WebGL/Flip_UV_01.efkefc_step0.png
+ Tests/WebGL/Flip_UV_02.efkefc_step0.png
+ Tests/WebGL/ForceFieldLocal_Old.efkefc_step0.png
+ Tests/WebGL/ForceFieldLocal_Turbulence1.efkefc_step0.png
+ Tests/WebGL/Gradient1.efkefc_step0.png
+ Tests/WebGL/Lighing_Parameters1.efkefc_step0.png
+ Tests/WebGL/Material_CustomData1.efkefc_step0.png
+ Tests/WebGL/Material_FresnelLike.efkefc_step0.png
+ Tests/WebGL/Material_FresnelRotatorPolarCoords.efkefc_step0.png
+ Tests/WebGL/Material_Lighting.efkefc_step0.png
+ Tests/WebGL/Material_Normal.efkefc_step0.png
+ Tests/WebGL/Material_Refraction.efkefc_step0.png
+ Tests/WebGL/Material_Refraction_Lighting.efkefc_step0.png
+ Tests/WebGL/Material_Sampler1.efkefc_step0.png
+ Tests/WebGL/Material_UV1.efkefc_step0.png
+ Tests/WebGL/Material_UV2.efkefc_step0.png
+ Tests/WebGL/Material_VertexColor.efkefc_step0.png
+ Tests/WebGL/Material_WorldPositionOffset.efkefc_step0.png
+ Tests/WebGL/Model_Parameters1.efk_step0.png
+ Tests/WebGL/ProcedualModel02.efkefc_step0.png
+ Tests/WebGL/ProcedualModel03.efkefc_step0.png
+ Tests/WebGL/Ribbon_Parameters1.efk_step0.png
+ Tests/WebGL/Ring_Parameters1.efk_step0.png
+ Tests/WebGL/RotateScale01.efkefc_step0.png
+ Tests/WebGL/SimpleLaser.efk_step0.png
+ Tests/WebGL/SpawnMethodParameter1.efkefc_step0.png
+ Tests/WebGL/Sprite_Parameters1.efk_step0.png
+ Tests/WebGL/Track_Parameters1.efk_step0.png
+ Tests/WebGL/Update_MultiModel.efkefc_step0.png
+ Tests/WebGL/hit_hanmado_0409.efkefc_step0.png
+ Tests/Windows/FollowParent01_DX11.png
+ Tests/Windows/ForceFieldLocal02_DX11.png
+ Tests/Windows/ForceFieldLocal03_DX11.png
+ Tests/Windows/ForceFieldLocal_Turbulence1_DX11.png
+ Tests/Windows/Simple_Turbulence_Fireworks_DX11.png
Loading