c_trace problem

Posted By: picoder

c_trace problem - 04/20/12 08:56

If I change position of a model immediately before tracing, c_trace checks this model according to previous position.

I changed small.c in samples folder for test:
Code:
function main()
{
	level_load("small.hmp"); 
	vec_set(camera.x,nullvector);
	vec_set(camera.pan,nullvector);
	ENTITY* target_ent = ent_create("earth.mdl", vector(0,0,1000), NULL);

	wait(-2);
	vec_set(target_ent.x,vector(100,0,0));

	//if target position bigger than 982, it works.
	c_trace(camera.x,vector(982,0,0),IGNORE_PASSABLE); 
	if (HIT_TARGET)
	{
		if(you==target_ent){beep();}
	}
}


Posted By: Superku

Re: c_trace problem - 04/20/12 10:19

This is no bug. You need to use c_move to update the position of the collision hull or wait until the end of the frame, then the hull will be updated automatically. You can set f.i. IGNORE_PASSABLE | IGNORE_MODELS | IGNORE_WORLD as the c_move mode, but when you set IGNORE_SPRITES, too (so all possible objects get ignored), then I think the hull won't get updated.

@jcl: I would like to see a function to update the collision hull manually so we don't have to use c_move for this purpose. A moving platform usually does not need collision detection, but its hull has to be updated before the end of the frame so the position/ height of the objects does not lag one frame behind.
Posted By: picoder

Re: c_trace problem - 04/20/12 11:39

You can immediately update collision hull (without polygon flag) by model position.

I didn't use c_move in test code but If I increase trace distance, c_trace can hit the target.
Code:
c_trace(camera.x,vector(990,0,0),IGNORE_PASSABLE);


If I need wait until the end of the frame, how does trace hit the target in the above code?




Posted By: Superku

Re: c_trace problem - 04/20/12 11:53

Quote:
You can immediately update collision hull (without polygon flag) by model position.

How do I do that?

EDIT: This should prove all my points:

Code:
///////////////////////////////
#include <acknex.h>
#include <default.c>
///////////////////////////////


void main()
{
	fps_max = 60;
	level_load(NULL);
	player = ent_create(CUBE_MDL,vector(100,50,0),NULL);
	while(1)
	{
		if(key_space) c_move(player,nullvector,vector(0,-100,0),IGNORE_PASSABLE | IGNORE_WORLD | IGNORE_MODELS);
		else player.y = -50;
		c_trace(vector(0,-50,0),vector(200,-50,0),IGNORE_PASSABLE | USE_POLYGON); 
		if(trace_hit) beep();
		if(key_space) c_move(player,nullvector,vector(0,100,0),IGNORE_PASSABLE | IGNORE_WORLD | IGNORE_MODELS);
		else player.y = 50;
		wait(1);
	}
}


Posted By: picoder

Re: c_trace problem - 04/20/12 12:07

You don't need anything. Please test my sample code.

Code:
function main()
{
	level_load("small.hmp"); 
	vec_set(camera.x,nullvector);
	vec_set(camera.pan,nullvector);
	ENTITY* target_ent = ent_create("earth.mdl", vector(0,0,1000), NULL);

	wait(-2);
	vec_set(target_ent.x,vector(100,0,0));

	//if target position bigger than 982, it works.
	c_trace(camera.x,vector(990,0,0),IGNORE_PASSABLE); 
	if (HIT_TARGET)
	{
		if(you==target_ent){beep();}
	}
}



Edit: If POLYGON flag of your target model is set or there is USE_POLYGON flag in c_trace, you're right. But my problem is different, it's about non-polygonal models.
Posted By: jcl

Re: c_trace problem - 04/20/12 14:22

This is not a bug - use c_updatehull when you need to update the collision hull.
Posted By: Superku

Re: c_trace problem - 04/20/12 14:30

There has to be a function that updates the position of the collision mesh at the end of each frame automatically that the engine uses internally (or the mesh's position gets set directly, I don't know). Could you make this function accessible in lite-C (so we can avoid unnecessary c_move calls)?
Posted By: picoder

Re: c_trace problem - 04/20/12 14:31

c_updatehull is very slow because it needs to reload the vertices of the model. But we just want to update position/rotations of collision hull. (especially for polygonal models) We don't want to change collision hull size or shape.
Posted By: picoder

Re: c_trace problem - 04/20/12 14:42

Originally Posted By: jcl
This is not a bug - use c_updatehull when you need to update the collision hull.


If I need use c_updatehull, how does trace hit the target in below code? (without c_updatehull or c_move)

Code:
function main()
{
	level_load("small.hmp"); 
	vec_set(camera.x,nullvector);
	vec_set(camera.pan,nullvector);
	ENTITY* target_ent = ent_create("earth.mdl", vector(0,0,1000), NULL);

	wait(-2);
	vec_set(target_ent.x,vector(100,0,0));

	//if target position bigger than 982, it works.
	c_trace(camera.x,vector(990,0,0),IGNORE_PASSABLE); 
	if (HIT_TARGET)
	{
		if(you==target_ent){beep();}
	}
}


Posted By: jcl

Re: c_trace problem - 04/23/12 06:38

Superku: Use c_updatehull for this. It's slow because it sorts the entitys' bounding box in the collision tree. But if you don't do it in the script, it's done at the end of the frame anyway. The only difference is that with c_updatehull you can determine the frame for the bounding box.

However, normally you can avoid such a situation anyway by proper coding, f.i. tracing an object before and not after displacing it.
Posted By: Superku

Re: c_trace problem - 04/23/12 10:29

Well AFAIK c_updatehull is mostly used to (re)calculate the collision mesh of a different frame. When I'm back home, I will test the speed of this instruction when the frame hasn't changed. If it's slower than c_move, it's useless in my case.

Quote:
However, normally you can avoid such a situation anyway by proper coding, f.i. tracing an object before and not after displacing it.

Not really, see the following situation:
A platform that moves vertically between two points up and down. It does not need collision detection when moving and should not be blocked by anything, so setting the z-position directly sounds logical. When the (PROC_LATE) player stands on the platform and performs his gravity code, he will get the position of the invisible collision mesh that is still at the position of the last frame.
Thus, because of the 1-frame-lag, he will either hover above the platform when it moves down or sink into it when the platform moves up.
To avoid this, I use c_move (instead of my.z = ...):
vec_diff(temp,new pos, old pos);
c_move(me,nullvector,temp,IGNORE_PASSABLE | IGNORE_MODELS | IGNORE_WORLD);
This updates the position of the collision mesh and the player and other objects on the platform don't lag one frame behind, but I think it's an unnecessary c_move call.
Btw. I've tried
c_move(me,nullvector,temp,IGNORE_SPRITES | IGNORE_MODELS | IGNORE_WORLD);
but it does not update the collision hull, I don't know if that is skipped on purpose or not.
Posted By: jcl

Re: c_trace problem - 04/23/12 11:23

The normal way to move a platform is c_move with ignoring all obstacles. Moving something by setting its coordinates is normally not recommended. Coordinates are only for placing something at a different position, f.i. for teleporting.

Anyway, at a first glance I see no reason why the collision tree is not updated when you set IGNORE_SPRITES. In my opinion, it should. Can you upload an example for this?
Posted By: Superku

Re: c_trace problem - 04/23/12 12:58

Hm I've tried to make an example, but it in fact works with (IGNORE_SPRITES | IGNORE_MODELS | IGNORE_WORLD) set. If you haven't changed c_move since ~January 2011, I was simply wrong - although I remember the issue as if it were yesterday.

Ok, then I will (continue to) use c_move with the said movement mode.
© 2024 lite-C Forums