Start block collisions

This commit is contained in:
Miloslav Ciz 2024-09-23 20:21:08 +02:00
parent c0aa81e79e
commit e068b02b9f
5 changed files with 159 additions and 11 deletions

100
racing.h
View file

@ -68,12 +68,103 @@ TPE_Vec3 _LCR_TPE_vec3DividePlain(TPE_Vec3 v, TPE_Unit d)
return v;
}
TPE_Vec3 _LCR_racingBlockEnvFunc(TPE_Vec3 point, const uint8_t *block)
{
uint8_t bx, by, bz;
LCR_mapBlockGetCoords(block,&bx,&by,&bz);
TPE_Vec3 center = TPE_vec3(
(((int) bx) - LCR_MAP_SIZE_BLOCKS / 2) * LCR_PHYSICS_UNIT
+ LCR_PHYSICS_UNIT / 2,
(((int) by) - LCR_MAP_SIZE_BLOCKS / 2) * (LCR_PHYSICS_UNIT / 2)
+ LCR_PHYSICS_UNIT / 4,
(((int) bz) - LCR_MAP_SIZE_BLOCKS / 2) * LCR_PHYSICS_UNIT
+ LCR_PHYSICS_UNIT / 2);
return TPE_envAABox(point,center,TPE_vec3(LCR_PHYSICS_UNIT / 2,
LCR_PHYSICS_UNIT / 4,LCR_PHYSICS_UNIT / 2));
}
TPE_Vec3 _LCR_racingEnvironmentFunction(TPE_Vec3 point, TPE_Unit maxDist)
{
return TPE_envAABoxInside(point,TPE_vec3(0,0,0),TPE_vec3(
// start with the map outside walls:
TPE_ENV_START(TPE_envAABoxInside(point,TPE_vec3(0,0,0),TPE_vec3(
LCR_PHYSICS_UNIT * LCR_MAP_SIZE_BLOCKS,
(LCR_PHYSICS_UNIT * LCR_MAP_SIZE_BLOCKS) / 2,
LCR_PHYSICS_UNIT * LCR_MAP_SIZE_BLOCKS));
LCR_PHYSICS_UNIT * LCR_MAP_SIZE_BLOCKS)),point)
const uint8_t *block = LCR_currentMap.blocks;
if (maxDist <= LCR_PHYSICS_UNIT / 4) // considering half of square height
{
/* Here we only check the 8 closest blocks => relatively fast. */
TPE_Vec3 pointShifted = TPE_vec3Plus(point,TPE_vec3(
(LCR_MAP_SIZE_BLOCKS / 2) * LCR_PHYSICS_UNIT,
(LCR_MAP_SIZE_BLOCKS / 4) * LCR_PHYSICS_UNIT,
(LCR_MAP_SIZE_BLOCKS / 2) * LCR_PHYSICS_UNIT));
uint8_t coords[6]; // x_low, x_high, y_low, y_high, z_low, z_high
coords[0] = (pointShifted.x / LCR_PHYSICS_UNIT);
coords[1] = (pointShifted.x % LCR_PHYSICS_UNIT < LCR_PHYSICS_UNIT / 2);
coords[2] = (pointShifted.y / (LCR_PHYSICS_UNIT / 2));
coords[3] =
(pointShifted.y % (LCR_PHYSICS_UNIT / 2) < LCR_PHYSICS_UNIT / 4);
coords[4] = (pointShifted.z / LCR_PHYSICS_UNIT);
coords[5] = (pointShifted.z % LCR_PHYSICS_UNIT < LCR_PHYSICS_UNIT / 2);
for (int i = 0; i < 6; i += 2)
if (coords[i + 1])
{
coords[i + 1] = coords[i];
coords[i] = coords[i] > 0 ? coords[i] - 1 : 0;
}
else
coords[i + 1] = coords[i] < 63 ? coords[i] + 1 : 63;
int start = 0, end = LCR_currentMap.blockCount - 1;
for (uint8_t i = 0; i < 8; ++i)
{
/* Black magic: here we make it so that we the lowest coord numbers
(0,0,0), then the highest (1,1,1), then second lowest (1,0,0), then
second highest (0,1,1) etc. This way we are narrowing the range (start,
end) for the binary search. */
int blockNum = LCR_mapGetBlockAtFast(
coords[0] + ((i ^ (i >> 1)) & 0x01),
coords[2] + ((i ^ (i >> 2)) & 0x01),
coords[4] + (i & 0x01),start,end);
if (blockNum >= 0) // is there a block at the coords?
{
TPE_ENV_NEXT(_LCR_racingBlockEnvFunc(point, // check it
LCR_currentMap.blocks + blockNum * LCR_BLOCK_SIZE),point)
// narrow the search range:
if (i % 2 == 0 && blockNum > start)
start = blockNum;
if (i % 2 && blockNum < end)
end = blockNum;
}
}
}
else
{
printf("oof\n");
/* Full check of all map blocks, slow, shouldn't happen often! */
for (int j = 0; j < LCR_currentMap.blockCount; ++j)
{
TPE_ENV_NEXT(_LCR_racingBlockEnvFunc(point,block),point)
block += LCR_BLOCK_SIZE;
}
}
TPE_ENV_END
}
LCR_GameUnit LCR_racingGetCarSpeed(void)
@ -164,6 +255,11 @@ void LCR_racingInit(void)
LCR_racing.carBody.elasticity = LCR_CAR_ELASTICITY;
LCR_racing.carBody.flags |= TPE_BODY_FLAG_ALWAYS_ACTIVE;
/* We disable bounding sphere checks because that would lead to calling env.
function with large min. distance which would lead to slow iteration over
all map blocks. */
LCR_racing.carBody.flags |= TPE_BODY_FLAG_NO_BSPHERE;
LCR_racingRestart();
}