6 registered members (AndrewAMD, Ayumi, degenerate_762, 7th_zorro, VoroneTZ, HoopyDerFrood),
1,268
guests, and 6
spiders. |
Key:
Admin,
Global Mod,
Mod
|
|
|
Re: bounce + low framerate ??
[Re: 3run]
#472264
04/18/18 13:06
04/18/18 13:06
|
Joined: Jun 2009
Posts: 2,210 Bavaria, Germany
Kartoffel
Expert
|
Expert
Joined: Jun 2009
Posts: 2,210
Bavaria, Germany
|
@Ezzett the way I understood it, 3run is already using calculations that are framerate independent but very low framerates still produce results that are "off"
I'm pretty certain it's due to the lower accuracy when running at a low framerate
@3run I don't really get it? from what I can see, the code is correct and it behaves the way it should?
POTATO-MAN saves the day! - Random
|
|
|
Re: bounce + low framerate ??
[Re: Kartoffel]
#472269
04/18/18 14:05
04/18/18 14:05
|
Joined: Jun 2007
Posts: 1,337 Hiporope and its pain
txesmi
Serious User
|
Serious User
Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
|
I think it has nothing to do with the frame rate. It only makes the entity describe a different trajectory, so at 20 fps it hits the edge between the two triangles of the plane, something that at 60 fps does not. But, why does it fail when it hits an edge? Who knows... I would bet it is a variable accuracy issue, as Kartoffel stated. 3dgs somehow interpolates the normals of the triangles when it hits an edge. As far as I know, the data has to be tranformed between coordinate systems and there are some small vectors involved that result in the normal vector. Plowed field for imprecision even for floats.
MATERIAL* mtlWireframe = {
effect = "
float4x4 matWorldViewProj;
void VS (in float4 InPos : POSITION, out float4 OutPos : POSITION) {
OutPos = mul(InPos, matWorldViewProj);
}
float4 PS() : COLOR0 {
return float4( 1.0f, 1.0f, 0.0f, 1.0f );
}
technique t0 {
pass p0 {
FillMode = Wireframe;
VertexShader = compile vs_2_0 VS();
PixelShader = compile ps_2_0 PS();
}
}
";
}
|
|
|
Re: bounce + low framerate ??
[Re: txesmi]
#472273
04/18/18 14:33
04/18/18 14:33
|
Joined: May 2009
Posts: 5,370 Caucasus
3run
OP
Senior Expert
|
OP
Senior Expert
Joined: May 2009
Posts: 5,370
Caucasus
|
from what I can see, the code is correct and it behaves the way it should? After some tests I guess it does.. but it just doesn't fit my expectations :< Damn... Thank you txesmi, and yes... thanks to your code, I can see that bounce get's fucked up when box hits the edge.. Another thing that I noticed, that it bounces off the surface different amount of time.. with fps 60 - 5 times, 20 - 6 times... If I lower fps while it's already bouncing, then it will cause to bounce off 7 times.. That sliding bounce effect was fixed by calculating bounce manually:
function get_bounce(VECTOR *speed, VECTOR *bounce_vec){
VECTOR temp_inverse;
vec_set(&temp_inverse, speed);
vec_inverse(&temp_inverse);
bounce_vec->x = speed->x + 2 * vec_dot(&normal, &temp_inverse) * normal.x;
bounce_vec->y = speed->y + 2 * vec_dot(&normal, &temp_inverse) * normal.y;
bounce_vec->z = speed->z + 2 * vec_dot(&normal, &temp_inverse) * normal.z;
}
Best regards! Thank you for your time guys. Edit: I think you need to implement a fourth order Runge-Kutta method to get correct results with large time_steps. Or just dive into the world of game physics literature that can drive you crazy (it depends on the knowledge you already have) https://www.amazon.com/gp/aw/d/012381976...&ref=plSrch Thank you for the link! I'll take a look at it.
Last edited by 3run; 04/18/18 14:35.
|
|
|
Re: bounce + low framerate ??
[Re: 3run]
#472275
04/18/18 14:47
04/18/18 14:47
|
Joined: May 2009
Posts: 5,370 Caucasus
3run
OP
Senior Expert
|
OP
Senior Expert
Joined: May 2009
Posts: 5,370
Caucasus
|
So far this is the best result I could get right now
#include <acknex.h>
#include <default.c>
#define PRAGMA_POINTER
// default trace/move flags
#define TRACE_FLAGS (IGNORE_ME | IGNORE_PASSABLE | IGNORE_PASSENTS | IGNORE_MAPS | IGNORE_SPRITES | IGNORE_CONTENT)
#define MOVE_FLAGS (IGNORE_ME | IGNORE_PASSABLE | IGNORE_PASSENTS | IGNORE_MAPS | IGNORE_SPRITES | IGNORE_CONTENT)
// collusion groups/push values
#define PUSH_GROUP 2
#define SWITCH_ITEM_GROUP 3
#define PATHFIND_GROUP 4
#define PLAYER_GROUP 5
#define TRAPS_GROUP 6
#define OBSTACLE_GROUP 7
#define LEVEL_GROUP 10
// vectors
#define speed_x skill50
#define speed_y skill51
#define speed_z skill52
#define obj_soil_contact skill69
// character controller (CCT) global parameters
var cct_gravity = 4; // gravity strength
var cct_gravity_max = 90; // gravity max strength
MATERIAL* mtlWireframe = {
effect = "
float4x4 matWorldViewProj;
void VS (in float4 InPos : POSITION, out float4 OutPos : POSITION) {
OutPos = mul(InPos, matWorldViewProj);
}
float4 PS() : COLOR0 {
return float4( 1.0f, 1.0f, 0.0f, 1.0f );
}
technique t0 {
pass p0 {
FillMode = Wireframe;
VertexShader = compile vs_2_0 VS();
PixelShader = compile ps_2_0 PS();
}
}
";
}
// calculate bounce vector
void get_bounce(VECTOR *speed, VECTOR *bounce_vec){
VECTOR temp_inverse;
vec_set(&temp_inverse, speed);
vec_inverse(&temp_inverse);
bounce_vec->x = speed->x + 2 * vec_dot(&normal, &temp_inverse) * normal.x;
bounce_vec->y = speed->y + 2 * vec_dot(&normal, &temp_inverse) * normal.y;
bounce_vec->z = speed->z + 2 * vec_dot(&normal, &temp_inverse) * normal.z;
}
// gravity trace for all npc
void prop_gravity(ENTITY *ent, var *z_force, var *soil, var offset){
if(!ent){ return; }
// gravity
if(*z_force <= 0){
VECTOR temp, target_vec;
vec_set(&temp, vector(ent->x, ent->y, ent->z - 150 + offset));
c_trace(&ent->x, &temp, TRACE_FLAGS | USE_BOX);
vec_set(&target_vec, &temp);
if(HIT_TARGET){ vec_set(&target_vec, &target); }
*soil = target_vec.z - offset;
}
// additional height buffer when ground contact to avoid player floating on slopes
if(ent->z > *soil + (5 + 20 * ent->obj_soil_contact) * time_step || *z_force > 0){
ent->obj_soil_contact = 0;
*z_force = maxv(*z_force - 9 * time_step, -90);
}
else{
c_move(ent, nullvector, vector(0, 0, *soil - ent->z), MOVE_FLAGS);
ent->obj_soil_contact = 1;
*z_force = 0;
}
if(*z_force){
// the maxv command makes sure you never move below the desired height
c_move(ent, nullvector, vector(0, 0, maxv(*z_force * time_step, *soil - ent->z)), MOVE_FLAGS);
}
}
action grenade(){
c_setminmax(my);
set(my, SHADOW | POLYGON);
VECTOR velocity;
vec_set(&velocity, vector(25, 0, 5));
vec_rotate(&velocity, &camera->pan);
var soil_height = 0; // target height from surface bellow
var gravity = 5; // 1 - 10 (default 5)
var restitution = 0.5; // 0.1 - 0.9 (default - 0.5)
var hit_count = 0;
var counter = 0;
while(my){
// still got go bounce ?
if(hit_count < 5){
VECTOR temp;
vec_set(&temp, &velocity);
vec_scale(&temp, time_step);
c_move(my, nullvector, &temp, MOVE_FLAGS);
velocity.z -= gravity * time_step;
if(HIT_TARGET){
hit_count++;
VECTOR bounce_vec;
get_bounce(&velocity, &bounce_vec);
var speed = vec_length(&velocity);
vec_set(&velocity, &bounce_vec);
vec_normalize(&velocity, restitution * speed);
}
}
else{
// reset all movement
vec_fill(&velocity, 0);
// simple gravity ?
prop_gravity(my, &my->speed_z, &soil_height, my->min_z);
}
counter += time_frame / 16;
if(counter >= 3){ break; }
wait(1);
}
safe_remove(my);
}
void main(){
shadow_stencil = 2;
fps_max = 60;
warn_level = 6;
level_load("");
wait(3);
camera->arc = 90;
vec_set(&camera->x, vector(-439, 0, 323));
vec_set(&camera->pan, vector(0, -36, 0));
level_ent = ent_create(CUBE_MDL, nullvector, NULL);
vec_set(&level_ent->scale_x, vector(256, 256, 0.1));
c_setminmax(level_ent);
set(level_ent, POLYGON | SHADOW);
//level_ent->material = mtlWireframe;
ENTITY *wall = ent_create(CUBE_MDL, vector(0, 256, 64), NULL);
vec_set(&wall->scale_x, vector(4, 8, 8));
c_setminmax(wall);
set(wall, POLYGON | SHADOW);
//wall->material = mtlWireframe;
int i = 0;
var counter = 0, throw = 0;
while(!key_esc){
if(mouse_left){
if(throw == 0){
ent_create(CUBE_MDL, &camera->x, grenade);
throw = 1;
}
}
if(throw == 1){
counter += time_frame / 16;
if(counter > 0.5){ throw = 0; counter -= 0.5; }
}
// slow down framerate for testing
if(key_e){ fps_max = 20; }
else{ fps_max = 60; }
DEBUG_VAR(fps_max, 0);
wait(1);
}
}
|
|
|
Re: bounce + low framerate ??
[Re: txesmi]
#472280
04/18/18 15:06
04/18/18 15:06
|
Joined: May 2009
Posts: 5,370 Caucasus
3run
OP
Senior Expert
|
OP
Senior Expert
Joined: May 2009
Posts: 5,370
Caucasus
|
Well, at least it does slide (right now ). It's perfectly fine the way it is, that's game dev. I bet txesmi has found the reason for why it behaves like it does.
In case you need deterministic/ framerate independent outcome (which you normally do NOT need), use a lockstep or fixed step approach and blend the visuals between old and new pos. I do/ did that for some multiplayer stuff, that's it. Thank you, Superku!
Last edited by 3run; 04/18/18 15:07.
|
|
|
|