mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-09-30 02:48:14 +03:00
ReignEngine: Implement camera quake effect
This commit is contained in:
@@ -55,6 +55,7 @@ extern struct RE_options RE_options;
|
||||
struct RE_camera {
|
||||
vec3 pos;
|
||||
float pitch, roll, yaw; // in degrees
|
||||
float quake_pitch, quake_yaw;
|
||||
};
|
||||
|
||||
struct RE_back_cg {
|
||||
@@ -183,6 +184,8 @@ bool RE_motion_set_frame_range(struct motion *motion, float begin, float end);
|
||||
bool RE_motion_set_loop_frame_range(struct motion *motion, float begin, float end);
|
||||
|
||||
int RE_effect_get_num_object(struct particle_effect *effect);
|
||||
bool RE_effect_get_camera_quake_flag(struct particle_effect *effect);
|
||||
bool RE_effect_set_camera_quake_flag(struct particle_effect *effect, bool enable);
|
||||
struct particle_object *RE_get_effect_object(struct particle_effect *effect, unsigned object);
|
||||
int RE_particle_get_type(struct particle_object *po);
|
||||
int RE_particle_get_move_type(struct particle_object *po);
|
||||
|
||||
@@ -190,7 +190,7 @@ enum particle_type {
|
||||
PARTICLE_TYPE_BILLBOARD = 0,
|
||||
PARTICLE_TYPE_POLYGON_OBJECT = 1,
|
||||
PARTICLE_TYPE_SWORD_BLUR = 2,
|
||||
PARTICLE_TYPE_CAMERA_VIBRATION = 3,
|
||||
PARTICLE_TYPE_CAMERA_QUAKE = 3,
|
||||
};
|
||||
|
||||
enum particle_move_type {
|
||||
@@ -331,9 +331,9 @@ struct particle_instance {
|
||||
struct particle_effect {
|
||||
char *path;
|
||||
struct hash_table *textures; // name -> struct billboard_texture*
|
||||
|
||||
int nr_objects;
|
||||
struct particle_object *objects;
|
||||
bool camera_quake_enabled;
|
||||
};
|
||||
|
||||
struct particle_effect *particle_effect_load(struct archive *aar, const char *path);
|
||||
|
||||
+26
-1
@@ -46,7 +46,7 @@ static enum particle_type parse_particle_type(const char *s)
|
||||
else if (!strcmp(s, "剣ブラー"))
|
||||
return PARTICLE_TYPE_SWORD_BLUR;
|
||||
else if (!strcmp(s, "カメラ振動"))
|
||||
return PARTICLE_TYPE_CAMERA_VIBRATION;
|
||||
return PARTICLE_TYPE_CAMERA_QUAKE;
|
||||
WARNING("unknown object type \"%s\"", s);
|
||||
return (enum particle_type)-1;
|
||||
}
|
||||
@@ -663,6 +663,7 @@ struct particle_effect *particle_effect_load(struct archive *aar, const char *pa
|
||||
archive_free_data(dfile);
|
||||
|
||||
effect->path = strdup(path);
|
||||
effect->camera_quake_enabled = true;
|
||||
load_textures(effect, aar);
|
||||
for (int i = 0; i < effect->nr_objects; i++) {
|
||||
struct particle_object *po = &effect->objects[i];
|
||||
@@ -744,6 +745,25 @@ void particle_effect_calc_frame_range(struct particle_effect *effect, struct mot
|
||||
motion->frame_end = end_frame;
|
||||
}
|
||||
|
||||
static void update_camera_quake(struct RE_instance *inst, struct particle_object *po)
|
||||
{
|
||||
float frame = inst->motion->current_frame - po->begin_frame;
|
||||
float total_frames = po->end_frame - po->begin_frame;
|
||||
if (frame < 0 || frame >= total_frames)
|
||||
return;
|
||||
|
||||
const float ease_in_duration = 4.0f;
|
||||
const float ease_out_duration = 4.0f;
|
||||
float amplitude = 1.0f;
|
||||
if (total_frames - frame < ease_out_duration)
|
||||
amplitude *= (total_frames - frame) / ease_out_duration;
|
||||
else if (frame < ease_in_duration)
|
||||
amplitude *= frame / ease_in_duration;
|
||||
|
||||
inst->plugin->camera.quake_pitch = sinf(frame * 1.1) * amplitude * -8.0f;
|
||||
inst->plugin->camera.quake_yaw = sinf(frame * 1.7) * amplitude * 12.0f;
|
||||
}
|
||||
|
||||
void particle_effect_update(struct RE_instance *inst)
|
||||
{
|
||||
struct particle_effect *effect = inst->effect;
|
||||
@@ -751,6 +771,11 @@ void particle_effect_update(struct RE_instance *inst)
|
||||
return;
|
||||
for (int i = 0; i < effect->nr_objects; i++) {
|
||||
struct particle_object *po = &effect->objects[i];
|
||||
if (po->type == PARTICLE_TYPE_CAMERA_QUAKE) {
|
||||
if (effect->camera_quake_enabled)
|
||||
update_camera_quake(inst, po);
|
||||
continue;
|
||||
}
|
||||
// These cannot be precomputed, because they may depend on the target's
|
||||
// *current* bone matrix.
|
||||
eval_pos_for_object(inst, po->position[0], po->pos.begin);
|
||||
|
||||
@@ -236,6 +236,8 @@ bool RE_build_model(struct RE_plugin *plugin, int elapsed_ms)
|
||||
if (!plugin)
|
||||
return false;
|
||||
|
||||
plugin->camera.quake_pitch = plugin->camera.quake_yaw = 0.0;
|
||||
|
||||
for (int i = 0; i < plugin->nr_instances; i++) {
|
||||
struct RE_instance *inst = plugin->instances[i];
|
||||
if (!inst)
|
||||
@@ -521,6 +523,19 @@ int RE_effect_get_num_object(struct particle_effect *effect)
|
||||
return effect ? effect->nr_objects : 0;
|
||||
}
|
||||
|
||||
bool RE_effect_get_camera_quake_flag(struct particle_effect *effect)
|
||||
{
|
||||
return effect && effect->camera_quake_enabled;
|
||||
}
|
||||
|
||||
bool RE_effect_set_camera_quake_flag(struct particle_effect *effect, bool enable)
|
||||
{
|
||||
if (!effect)
|
||||
return false;
|
||||
effect->camera_quake_enabled = enable;
|
||||
return true;
|
||||
}
|
||||
|
||||
struct particle_object *RE_get_effect_object(struct particle_effect *effect, unsigned object)
|
||||
{
|
||||
if (!effect || object >= (unsigned)effect->nr_objects)
|
||||
|
||||
+4
-3
@@ -259,8 +259,8 @@ void RE_calc_view_matrix(struct RE_camera *camera, vec3 up, mat4 out)
|
||||
{
|
||||
vec3 front = { 0.0, 0.0, -1.0 };
|
||||
vec3 euler = {
|
||||
glm_rad(camera->pitch),
|
||||
glm_rad(camera->yaw),
|
||||
glm_rad(camera->pitch + camera->quake_pitch),
|
||||
glm_rad(camera->yaw + camera->quake_yaw),
|
||||
glm_rad(camera->roll)
|
||||
};
|
||||
mat4 rot;
|
||||
@@ -538,7 +538,8 @@ static void render_particle_effect(struct RE_instance *inst, struct RE_renderer
|
||||
case PARTICLE_TYPE_POLYGON_OBJECT:
|
||||
render_polygon_particles(r, inst, po, inst->motion->current_frame);
|
||||
break;
|
||||
case PARTICLE_TYPE_SWORD_BLUR: // unused
|
||||
case PARTICLE_TYPE_SWORD_BLUR: // unused
|
||||
case PARTICLE_TYPE_CAMERA_QUAKE: // handled in particle_effect_update()
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+14
-6
@@ -1022,10 +1022,18 @@ static float ReignEngine_GetEffectObjectOffsetY(int plugin, int instance, int ob
|
||||
|
||||
//bool ReignEngine_SetEffectObjectOffsetX(int plugin, int instance, int nObject, float fOffsetX);
|
||||
//bool ReignEngine_SetEffectObjectOffsetY(int plugin, int instance, int nObject, float fOffsetY);
|
||||
HLL_WARN_UNIMPLEMENTED(false, bool, ReignEngine, GetCameraQuakeEffectFlag, int plugin, int instance);
|
||||
HLL_WARN_UNIMPLEMENTED(false, bool, ReignEngine, SetCameraQuakeEffectFlag, int plugin, int instance, bool flag);
|
||||
|
||||
bool ReignEngine_SetCameraPos(int plugin, float x, float y, float z)
|
||||
static bool ReignEngine_GetCameraQuakeEffectFlag(int plugin, int instance)
|
||||
{
|
||||
return RE_effect_get_camera_quake_flag(get_effect(plugin, instance));
|
||||
}
|
||||
|
||||
static bool ReignEngine_SetCameraQuakeEffectFlag(int plugin, int instance, bool flag)
|
||||
{
|
||||
return RE_effect_set_camera_quake_flag(get_effect(plugin, instance), flag);
|
||||
}
|
||||
|
||||
static bool ReignEngine_SetCameraPos(int plugin, float x, float y, float z)
|
||||
{
|
||||
struct RE_plugin *p = get_plugin(plugin);
|
||||
if (!p)
|
||||
@@ -1036,7 +1044,7 @@ bool ReignEngine_SetCameraPos(int plugin, float x, float y, float z)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReignEngine_SetCameraAngle(int plugin, float angle)
|
||||
static bool ReignEngine_SetCameraAngle(int plugin, float angle)
|
||||
{
|
||||
struct RE_plugin *p = get_plugin(plugin);
|
||||
if (!p)
|
||||
@@ -1045,7 +1053,7 @@ bool ReignEngine_SetCameraAngle(int plugin, float angle)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReignEngine_SetCameraAngleP(int plugin, float angle_p)
|
||||
static bool ReignEngine_SetCameraAngleP(int plugin, float angle_p)
|
||||
{
|
||||
struct RE_plugin *p = get_plugin(plugin);
|
||||
if (!p)
|
||||
@@ -1054,7 +1062,7 @@ bool ReignEngine_SetCameraAngleP(int plugin, float angle_p)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReignEngine_SetCameraAngleB(int plugin, float angle_b)
|
||||
static bool ReignEngine_SetCameraAngleB(int plugin, float angle_b)
|
||||
{
|
||||
struct RE_plugin *p = get_plugin(plugin);
|
||||
if (!p)
|
||||
|
||||
Reference in New Issue
Block a user