Created
August 21, 2019 14:01
-
-
Save kei-y/180999193b57a6dceef2ca1e59ad043c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// | |
// 解説 | |
// | |
// | |
// $HeadURL: https://svnrepos.sandlot.jp/svn/repos/FUSHIMI/trunk/Program/SourceFiles/Game/Object/Effect/GlassClashEffect.cpp $ | |
// $Id: GlassClashEffect.cpp 1077 2019-08-21 13:45:18Z prg_y_horiuchi $ | |
// | |
//------------------------------------------------------------------------------ | |
// include files | |
//------------------------------------------------------------------------------ | |
#include "stdafx.h" | |
#include "GlassClashEffect.h" | |
#include "../Effect/EffectGenUtil.h" | |
#include <sgs/db/db_Output.h> | |
#include <sgs/mt/mt_Utility.h> | |
#include <xgs/game/game_System.h> | |
#include <xgs/xgs_Global.h> | |
#include <xgs/Havok/havok_Utility.h> | |
#include <Physics2012/Dynamics/Phantom/hkpAabbPhantom.h> | |
#include <Physics2012/Collide/Query/Collector/RayCollector/hkpClosestRayHitCollector.h> | |
#include <Physics2012/Collide/Query/Collector/PointCollector/hkpSimpleClosestContactCollector.h> | |
// #include <xgs/debug/debug_Utility.h> | |
#include "../../Collision/HitQueryUtility.h" | |
//------------------------------------------------------------------------------ | |
// compile switch | |
//------------------------------------------------------------------------------ | |
//------------------------------------------------------------------------------ | |
// constant | |
//------------------------------------------------------------------------------ | |
//------------------------------------------------------------------------------ | |
// macro | |
//------------------------------------------------------------------------------ | |
//------------------------------------------------------------------------------ | |
// type | |
//------------------------------------------------------------------------------ | |
//------------------------------------------------------------------------------ | |
// class | |
//------------------------------------------------------------------------------ | |
//------------------------------------------------------------------------------ | |
// global function | |
//------------------------------------------------------------------------------ | |
//------------------------------------------------------------------------------ | |
// local variable | |
//------------------------------------------------------------------------------ | |
//------------------------------------------------------------------------------ | |
// コンストラクタ | |
//------------------------------------------------------------------------------ | |
GlassClashEffect::GlassClashEffect(const InitParamBase& _init_param) : SceneObject(_init_param) | |
{ | |
if (CheckLimitter(EFFECT_LIMITTER_INDEX_CRASH_GLASS, 1, 100) == false) | |
return; | |
EnableCallback(CB_UPDATE | CB_SYNC_RENDER); | |
const InitParam& init_param = _init_param.cast<const InitParam>(); | |
SGS_WARNING(init_param.m_reduction_level > 0); | |
m_gravity = 9.80665f / 60.0f / 60.0f; | |
// 大きいガラス片 | |
{ | |
ParticleEmitterCore::InitParam particle_param; | |
particle_param.m_max_count = 5; | |
particle_param.m_alive_time_min = uint32_t(init_param.m_size * 25.0f); | |
particle_param.m_alive_time_max = particle_param.m_alive_time_min * 2; | |
particle_param.m_blend_mode = xgl::ren::DrawUtility::BLEND_ALPHA; | |
// particle_param.m_air_resistance = 0.98f; | |
particle_param.m_air_resistance = 1.0f; | |
particle_param.m_gravity.Set(0.0f, -m_gravity, 0.0f); | |
particle_param.m_direction.m_angle_min = 0.0f; | |
particle_param.m_direction.m_angle_max = sgs::mt::PI * 0.125f; | |
particle_param.m_rotate.m_min = 0.0f; | |
particle_param.m_rotate.m_max = 0.0f; | |
particle_param.m_rotate.m_speed_min = 0.0f; | |
particle_param.m_rotate.m_speed_max = 0.0f; | |
particle_param.m_speed.m_factor = ParticleEmitterCore::InitParam::RANDOM_FACTOR_SPEED; | |
particle_param.m_speed.m_min = 0.0f; | |
particle_param.m_speed.m_max = init_param.m_size * 0.1f; | |
particle_param.m_size.m_factor = ParticleEmitterCore::InitParam::RANDOM_FACTOR_SPEED; | |
particle_param.m_size.m_min = init_param.m_size * 0.4f; | |
particle_param.m_size.m_max = particle_param.m_size.m_min * 2.0f; | |
particle_param.m_size.m_inc = 0; | |
particle_param.m_color.m_base.Set(1.0f, 1.0f, 1.0f, 1.0f); | |
particle_param.m_color.m_fade_out.Set(1.0f, 1.0f, 1.0f, 0.0f); | |
particle_param.m_texture.m_instance = EffectGenUtil::Instance().GetTexture(L"ガラス片小_01.dds"); | |
particle_param.m_lighting.m_is_enable = true; | |
// particle_param.m_lighting.m_prim_normal_weight = 1.0f; | |
// particle_param.m_lighting.m_round_normal_weight = 1.0f; | |
particle_param.m_lighting.m_view_normal_weight = 1.0f; | |
m_large_particle.Initialize(particle_param); | |
// エミット | |
m_large_particle.Emit(init_param.m_position, init_param.m_normal, 5 / init_param.m_reduction_level); | |
} | |
// 小さいガラス片 | |
{ | |
ParticleEmitterCore::InitParam particle_param; | |
particle_param.m_max_count = 5; | |
particle_param.m_alive_time_min = uint32_t(init_param.m_size * 25.0f); | |
particle_param.m_alive_time_max = particle_param.m_alive_time_min * 2; | |
particle_param.m_blend_mode = xgl::ren::DrawUtility::BLEND_ALPHA; | |
// particle_param.m_air_resistance = 0.98f; | |
particle_param.m_air_resistance = 1.0f; | |
particle_param.m_gravity.Set(0.0f, -m_gravity, 0.0f); | |
particle_param.m_direction.m_angle_min = 0.0f; | |
particle_param.m_direction.m_angle_max = sgs::mt::PI * 0.25f; | |
particle_param.m_rotate.m_min = 0.0f; | |
particle_param.m_rotate.m_max = 0.0f; | |
particle_param.m_rotate.m_speed_min = 0.0f; | |
particle_param.m_rotate.m_speed_max = 0.0f; | |
particle_param.m_speed.m_factor = ParticleEmitterCore::InitParam::RANDOM_FACTOR_SPEED; | |
particle_param.m_speed.m_min = 0.0f; | |
particle_param.m_speed.m_max = init_param.m_size * 0.1f; | |
particle_param.m_size.m_factor = ParticleEmitterCore::InitParam::RANDOM_FACTOR_SPEED; | |
particle_param.m_size.m_min = init_param.m_size * 0.3f; | |
particle_param.m_size.m_max = particle_param.m_size.m_min * 2.0f; | |
particle_param.m_size.m_inc = 0; | |
particle_param.m_color.m_base.Set(1.0f, 1.0f, 1.0f, 1.0f); | |
particle_param.m_color.m_fade_out.Set(1.0f, 1.0f, 1.0f, 0.0f); | |
particle_param.m_texture.m_instance = EffectGenUtil::Instance().GetTexture(L"ガラス片小_02.dds"); | |
particle_param.m_lighting.m_is_enable = true; | |
// particle_param.m_lighting.m_prim_normal_weight = 1.0f; | |
// particle_param.m_lighting.m_round_normal_weight = 1.0f; | |
particle_param.m_lighting.m_view_normal_weight = 1.0f; | |
m_small_particle.Initialize(particle_param); | |
// エミット | |
m_small_particle.Emit(init_param.m_position, init_param.m_normal, 5 / init_param.m_reduction_level); | |
} | |
// 砕ける破片 | |
{ | |
m_particle_position = init_param.m_position; | |
m_emit_vector = init_param.m_normal; | |
m_emit_vector.Normalize(); | |
m_emit_vector = sgs::mt::MakeRandomVector(m_emit_vector, 0.0f, sgs::mt::PI * 0.25f); // ランダムベクトル | |
m_emit_vector.Mul(init_param.m_size * sgs::mt::Random32::global.Float(0.03f, 0.1f)); | |
m_particle_position += m_emit_vector; // 壁にめり込まないように | |
m_start_alpha = sgs::mt::Random32::global.Float(0.5f, 1.0f); | |
m_clash_particle.pos = init_param.m_position; | |
m_clash_particle.color = sgs::mt::Color(1.0f, 1.0f, 1.0f, m_start_alpha); | |
m_clash_particle.size = | |
init_param.m_size * sgs::mt::Random32::global.Float(0.25f, 0.4f); // 大きいので縮小(ランダム) | |
m_clash_particle.rad = 0.0f; | |
m_clash_particle.nrm = init_param.m_normal; | |
m_clash_particle.pat_no = 1; //? | |
m_clash_texture = EffectGenUtil::Instance().GetTexture(L"ガラス片大_01.dds"); | |
xgl::gs::SamplerState::InitParam sampler_init_param; | |
sampler_init_param.m_mip_lod_bias = 0; | |
m_clash_sampler.Initialize(xgs::g_device, sampler_init_param); | |
m_ground_hit = false; | |
m_use_clash_particle = true; | |
m_particle_alpha = m_start_alpha; | |
if (sgs::mt::Random32::global.Integer(0, 100) > 60) | |
{ | |
m_ground_hit = true; // 砕ける破片を表示させない | |
m_use_clash_particle = false; | |
} | |
// 砕けたガラス片パーティクル | |
ParticleEmitterCore::InitParam particle_param; | |
particle_param.m_max_count = 20; | |
particle_param.m_alive_time_min = uint32_t(init_param.m_size * 50.0f); | |
particle_param.m_alive_time_max = uint32_t(init_param.m_size * 50.0f); | |
particle_param.m_blend_mode = xgl::ren::DrawUtility::BLEND_ALPHA; | |
// particle_param.m_air_resistance = 0.98f; | |
particle_param.m_gravity.Set(0.0f, -m_gravity, 0.0f); | |
particle_param.m_direction.m_angle_min = 0.0f; | |
particle_param.m_direction.m_angle_max = sgs::mt::PI * 0.25f; | |
particle_param.m_rotate.m_min = 0.0f; | |
particle_param.m_rotate.m_max = 0.0f; | |
particle_param.m_rotate.m_speed_min = 0.0f; | |
particle_param.m_rotate.m_speed_max = 0.0f; | |
particle_param.m_speed.m_factor = ParticleEmitterCore::InitParam::RANDOM_FACTOR_SPEED; | |
particle_param.m_speed.m_min = 0.0f; | |
particle_param.m_speed.m_max = init_param.m_size * 0.05f; | |
particle_param.m_size.m_factor = ParticleEmitterCore::InitParam::RANDOM_FACTOR_SPEED; | |
particle_param.m_size.m_min = m_clash_particle.size; | |
particle_param.m_size.m_max = m_clash_particle.size; | |
particle_param.m_size.m_inc = 0; | |
particle_param.m_color.m_base.Set(1.0f, 1.0f, 1.0f, 1.0f); | |
particle_param.m_color.m_fade_out.Set(1.0f, 1.0f, 1.0f, 0.0f); | |
particle_param.m_texture.m_instance = EffectGenUtil::Instance().GetTexture(L"ガラス片小_02.dds"); | |
particle_param.m_lighting.m_is_enable = true; | |
// particle_param.m_lighting.m_prim_normal_weight = 1.0f; | |
// particle_param.m_lighting.m_round_normal_weight = 1.0f; | |
particle_param.m_lighting.m_view_normal_weight = 0.5f; | |
m_splash_particle.Initialize(particle_param); | |
} | |
m_time = 0; | |
m_timelimit = uint32_t(init_param.m_size * 50.0f); | |
// aabb計算(とりあえず) | |
sgs::mt::Vector size(2.0f, 2.0f, 2.0f); | |
m_local_aabb.m_pos = init_param.m_position; | |
m_local_aabb.m_size = size * 0.5f; | |
sgs::mt::Matrix mat; | |
xgs::umbra::Object::Initialize(xgs::game::System::Instance().GetUmbraCell(), mat, xgs::g_device); | |
xgs::umbra::Object::imdSetOpacity(false); // 不透明フェーズでの描画OFF | |
xgs::umbra::Object::imdSetTransparent(true); // 半透明フェーズでの描画ON | |
xgs::umbra::Object::imdSetRenderCost(Umbra::Object::CHEAP); // エフェクト処理なのでカリングが弱くても気にしない | |
xgs::umbra::Object::imdSetProperty(Umbra::Object::OCCLUDER, false); // 描画時に深度情報は出力しないのでfalse | |
} | |
//------------------------------------------------------------------------------ | |
// デストラクタ | |
//------------------------------------------------------------------------------ | |
GlassClashEffect::~GlassClashEffect() | |
{ | |
} | |
//------------------------------------------------------------------------------ | |
// 同期 | |
//------------------------------------------------------------------------------ | |
void GlassClashEffect::OnSyncRender() | |
{ | |
m_large_particle.SyncRender(); | |
m_small_particle.SyncRender(); | |
m_splash_particle.SyncRender(); | |
m_clash_particle.pos = m_particle_position; | |
m_clash_particle.color.a = m_particle_alpha; | |
sgs::mt::MatrixNC m; | |
CalcAabb(m); | |
xgs::umbra::Object::imdSetObb(m); | |
} | |
//------------------------------------------------------------------------------ | |
// 更新 | |
//------------------------------------------------------------------------------ | |
void GlassClashEffect::OnUpdate(const xgs::game::UpdateContext& context) | |
{ | |
// パーティクル部分 | |
m_large_particle.Update(context); | |
m_small_particle.Update(context); | |
m_splash_particle.Update(context); | |
// レイキャストテスト | |
if (m_ground_hit == false) | |
{ | |
// カラー遷移(alpha値のみ) | |
float time_factor = (float)m_time / (float)m_timelimit; | |
m_particle_alpha = m_start_alpha * (1.0f - time_factor); | |
sgs::mt::Vector next_position(m_particle_position); | |
next_position += m_emit_vector; | |
sgs::mt::Vector difference_vec(next_position - m_particle_position); | |
difference_vec.Abs(); | |
hknpClosestHitCollector collector; | |
xgs::havok::CastRaySettings settings; | |
settings.m_from = m_particle_position; | |
settings.m_to = next_position; | |
settings.m_filter_info = CollisionFilter::Instance().CalcForMapSearchFilter(); | |
xgs::havok::CastRayToWorld(xgs::game::System::Instance().World(), collector, settings); | |
if (collector.hasHit()) | |
{ | |
// 地面HIT | |
m_ground_hit = true; | |
// 1回かけらを撒く(パーティクル) | |
sgs::mt::Vector position = XGS_TO_SGSVECTOR(collector.getHit().m_position); | |
sgs::mt::Vector normal = XGS_TO_SGSVECTOR(collector.getHit().m_normal); | |
sgs::mt::Vector ref_vec(m_emit_vector); | |
ref_vec.Reflection(normal); | |
m_splash_particle.Emit(position, normal, 5); | |
m_timelimit *= 2; // 砕けたパーティクル消失までの時間分増加 | |
} | |
// 砕ける予定のパーティクルの座標更新 | |
m_particle_position += m_emit_vector; | |
m_emit_vector += sgs::mt::Vector(0.0f, -m_gravity, 0.0f); | |
// m_emit_vector.Mul(0.98f); // 空気抵抗値 | |
} | |
// aabb作成 | |
sgs::mt::Aabb temp_aabb; | |
// 砕けるパーティクル | |
if (m_use_clash_particle == true) | |
{ | |
if (m_ground_hit == false) | |
{ | |
// 砕ける前 | |
temp_aabb.m_size.Set(m_clash_particle.size, m_clash_particle.size, m_clash_particle.size); | |
temp_aabb.m_pos = m_clash_particle.pos; | |
} | |
else | |
{ | |
// 砕けた後 | |
temp_aabb = m_splash_particle.AABB(); | |
} | |
} | |
else | |
{ | |
temp_aabb.m_pos = m_particle_position; | |
temp_aabb.m_size.Set(0.1f, 0.1f, 0.1f); | |
} | |
// aabb合成 | |
if (m_small_particle.IsEnd() == false) | |
{ | |
temp_aabb.Combine(m_small_particle.AABB()); | |
} | |
if (m_large_particle.IsEnd() == false) | |
{ | |
temp_aabb.Combine(m_large_particle.AABB()); | |
} | |
// if( m_splash_particle.IsEnd() == false ){temp_aabb.Combine(m_splash_particle.AABB());} | |
m_local_aabb = temp_aabb; | |
if (m_time++ > m_timelimit) | |
{ | |
// 削除 | |
Delete(); | |
} | |
} | |
//------------------------------------------------------------------------------ | |
// レンダリング | |
//------------------------------------------------------------------------------ | |
void GlassClashEffect::OnRender(xgl::gs::Context& context, | |
RenderPhase phase, | |
const xgs::umbra::RenderSetting& render_setting) | |
{ | |
m_large_particle.Render(context, sgs::mt::UNIT_MATRIX); | |
m_small_particle.Render(context, sgs::mt::UNIT_MATRIX); | |
m_splash_particle.Render(context, sgs::mt::UNIT_MATRIX); | |
if (m_ground_hit == false) | |
{ | |
xgs::g_draw_utility.imdSetState(context, false, xgl::ren::DrawUtility::BLEND_ALPHA); | |
xgs::g_draw_utility.imdSetSampler(context, m_clash_sampler, m_clash_texture); | |
xgs::g_draw_utility.imdDrawLightParticle(context, sgs::mt::UNIT_MATRIX, &m_clash_particle, 1, 1.0f, 0.1f, 1.0f); | |
} | |
} | |
//------------------------------------------------------------------------------ | |
// Aabb作成 | |
//------------------------------------------------------------------------------ | |
void GlassClashEffect::CalcAabb(sgs::mt::Matrix& dest) | |
{ | |
sgs::mt::Aabb aabb; | |
aabb.SetTransformAABB(m_local_aabb, m_matrix); | |
aabb.m_size.Max(sgs::mt::Vector(0.1f, 0.1f, 0.1f)); | |
dest[0].Set(aabb.m_size.x, 0.0f, 0.0f, 0.0f); | |
dest[1].Set(0.0f, aabb.m_size.y, 0.0f, 0.0f); | |
dest[2].Set(0.0f, 0.0f, aabb.m_size.z, 0.0f); | |
dest[3] = aabb.m_pos; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment