mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-13 16:44:50 +02:00
TR1 Lara state changes and collision re-implementation (close to original)
This commit is contained in:
@@ -31,8 +31,7 @@ struct Character : Controller {
|
|||||||
WALK = 1 << 6,
|
WALK = 1 << 6,
|
||||||
ACTION = 1 << 7,
|
ACTION = 1 << 7,
|
||||||
WEAPON = 1 << 8,
|
WEAPON = 1 << 8,
|
||||||
LOOK = 1 << 9,
|
LOOK = 1 << 9
|
||||||
DEATH = 1 << 10
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Controller *viewTarget;
|
Controller *viewTarget;
|
||||||
@@ -143,10 +142,11 @@ struct Character : Controller {
|
|||||||
virtual int getStateWade() { return state; }
|
virtual int getStateWade() { return state; }
|
||||||
virtual int getStateDeath() { return state; }
|
virtual int getStateDeath() { return state; }
|
||||||
virtual int getStateDefault() { return state; }
|
virtual int getStateDefault() { return state; }
|
||||||
virtual int getInput() { return health <= 0 ? DEATH : 0; }
|
virtual int getInput() { return 0; }
|
||||||
virtual bool useHeadAnimation() { return false; }
|
virtual bool useHeadAnimation() { return false; }
|
||||||
|
|
||||||
int getNextState() {
|
int getNextState() {
|
||||||
|
/*
|
||||||
if (input & DEATH) {
|
if (input & DEATH) {
|
||||||
int deathState = getStateDeath();
|
int deathState = getStateDeath();
|
||||||
if (state == deathState || animation.canSetState(deathState)) {
|
if (state == deathState || animation.canSetState(deathState)) {
|
||||||
@@ -155,7 +155,7 @@ struct Character : Controller {
|
|||||||
return deathState;
|
return deathState;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
switch (stand) {
|
switch (stand) {
|
||||||
case STAND_AIR : return getStateAir();
|
case STAND_AIR : return getStateAir();
|
||||||
case STAND_GROUND : return getStateGround();
|
case STAND_GROUND : return getStateGround();
|
||||||
|
@@ -573,7 +573,7 @@ namespace Debug {
|
|||||||
TR::StaticMesh *sm = &level.staticMeshes[m.meshIndex];
|
TR::StaticMesh *sm = &level.staticMeshes[m.meshIndex];
|
||||||
|
|
||||||
Box box;
|
Box box;
|
||||||
vec3 offset = vec3(float(m.x), float(m.y), float(m.z));
|
vec3 offset = vec3(float(m.pos.x), float(m.pos.y), float(m.pos.z));
|
||||||
sm->getBox(false, m.rotation, box); // visible box
|
sm->getBox(false, m.rotation, box); // visible box
|
||||||
|
|
||||||
Debug::Draw::box(offset + box.min, offset + box.max, vec4(1, 1, 0, 0.25));
|
Debug::Draw::box(offset + box.min, offset + box.max, vec4(1, 1, 0, 0.25));
|
||||||
|
117
src/format.h
117
src/format.h
@@ -1274,7 +1274,7 @@
|
|||||||
E( MESHSWAP1 ) \
|
E( MESHSWAP1 ) \
|
||||||
E( MESHSWAP2 ) \
|
E( MESHSWAP2 ) \
|
||||||
E( MESHSWAP3 ) \
|
E( MESHSWAP3 ) \
|
||||||
E( DEATH_SLIDE ) \
|
E( ZIPLINE ) \
|
||||||
E( BODY_PART ) \
|
E( BODY_PART ) \
|
||||||
E( CAMERA_TARGET ) \
|
E( CAMERA_TARGET ) \
|
||||||
E( WATERFALL1 ) \
|
E( WATERFALL1 ) \
|
||||||
@@ -1382,6 +1382,7 @@ namespace TR {
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
NO_FLOOR = -127,
|
NO_FLOOR = -127,
|
||||||
|
NO_VALUE = NO_FLOOR * 256,
|
||||||
NO_ROOM = 0xFF,
|
NO_ROOM = 0xFF,
|
||||||
NO_BOX = 0xFFFF,
|
NO_BOX = 0xFFFF,
|
||||||
NO_WATER = 0x7FFFFFFF,
|
NO_WATER = 0x7FFFFFFF,
|
||||||
@@ -1617,7 +1618,7 @@ namespace TR {
|
|||||||
}
|
}
|
||||||
|
|
||||||
union fixed {
|
union fixed {
|
||||||
uint32 value;
|
int32 value;
|
||||||
struct {
|
struct {
|
||||||
uint16 L;
|
uint16 L;
|
||||||
int16 H;
|
int16 H;
|
||||||
@@ -1887,7 +1888,7 @@ namespace TR {
|
|||||||
} *lights;
|
} *lights;
|
||||||
|
|
||||||
struct Mesh {
|
struct Mesh {
|
||||||
int32 x, y, z;
|
vec3i pos;
|
||||||
angle rotation;
|
angle rotation;
|
||||||
uint16 meshID;
|
uint16 meshID;
|
||||||
Color32 color;
|
Color32 color;
|
||||||
@@ -1987,6 +1988,12 @@ namespace TR {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum SlantType {
|
||||||
|
SLANT_NONE,
|
||||||
|
SLANT_LOW,
|
||||||
|
SLANT_HIGH
|
||||||
|
};
|
||||||
|
|
||||||
union FloorData {
|
union FloorData {
|
||||||
uint16 value;
|
uint16 value;
|
||||||
union Command {
|
union Command {
|
||||||
@@ -2015,6 +2022,9 @@ namespace TR {
|
|||||||
};
|
};
|
||||||
} triggerCmd;
|
} triggerCmd;
|
||||||
|
|
||||||
|
FloorData() {}
|
||||||
|
FloorData(uint16 value) : value(value) {}
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
NONE
|
NONE
|
||||||
, PORTAL
|
, PORTAL
|
||||||
@@ -2661,6 +2671,18 @@ namespace TR {
|
|||||||
|
|
||||||
vec3 min() const { return vec3((float)minX, (float)minY, (float)minZ); }
|
vec3 min() const { return vec3((float)minX, (float)minY, (float)minZ); }
|
||||||
vec3 max() const { return vec3((float)maxX, (float)maxY, (float)maxZ); }
|
vec3 max() const { return vec3((float)maxX, (float)maxY, (float)maxZ); }
|
||||||
|
|
||||||
|
MinMax lerp(const MinMax &b, int32 mod, int32 rate) const {
|
||||||
|
#define LERP(v) r.##v = v + ((b.##v - v) * mod) / rate;
|
||||||
|
|
||||||
|
MinMax r;
|
||||||
|
LERP(minX); LERP(maxX);
|
||||||
|
LERP(minY); LERP(maxY);
|
||||||
|
LERP(minZ); LERP(maxZ);
|
||||||
|
return r;
|
||||||
|
|
||||||
|
#undef LERP
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AnimFrame {
|
struct AnimFrame {
|
||||||
@@ -2744,8 +2766,13 @@ namespace TR {
|
|||||||
MinMax cbox;
|
MinMax cbox;
|
||||||
uint16 flags;
|
uint16 flags;
|
||||||
|
|
||||||
|
BoxV2 getBox(bool collision) {
|
||||||
|
MinMax &b = collision ? cbox : vbox;
|
||||||
|
return BoxV2(vec3i(b.minX, b.minY, b.minZ), vec3i(b.maxX, b.maxY, b.maxZ));
|
||||||
|
}
|
||||||
|
|
||||||
void getBox(bool collision, angle rotation, ::Box &box) {
|
void getBox(bool collision, angle rotation, ::Box &box) {
|
||||||
int k = rotation.value / 0x4000;
|
int k = rotation.value / ANGLE_90;
|
||||||
|
|
||||||
MinMax &m = collision ? cbox : vbox;
|
MinMax &m = collision ? cbox : vbox;
|
||||||
|
|
||||||
@@ -3997,9 +4024,9 @@ namespace TR {
|
|||||||
room->meshes = room->meshesCount ? new Room::Mesh[room->meshesCount] : NULL;
|
room->meshes = room->meshesCount ? new Room::Mesh[room->meshesCount] : NULL;
|
||||||
for (int i = 0; i < room->meshesCount; i++) {
|
for (int i = 0; i < room->meshesCount; i++) {
|
||||||
Room::Mesh &m = room->meshes[i];
|
Room::Mesh &m = room->meshes[i];
|
||||||
m.x = stream.readBE32();
|
m.pos.x = stream.readBE32();
|
||||||
m.y = stream.readBE32();
|
m.pos.y = stream.readBE32();
|
||||||
m.z = stream.readBE32();
|
m.pos.z = stream.readBE32();
|
||||||
m.rotation.value = stream.readBE16();
|
m.rotation.value = stream.readBE16();
|
||||||
uint16 intensity = stream.readBE16();
|
uint16 intensity = stream.readBE16();
|
||||||
stream.readBE16();
|
stream.readBE16();
|
||||||
@@ -5462,9 +5489,9 @@ namespace TR {
|
|||||||
r.meshes = r.meshesCount ? new Room::Mesh[r.meshesCount] : NULL;
|
r.meshes = r.meshesCount ? new Room::Mesh[r.meshesCount] : NULL;
|
||||||
for (int i = 0; i < r.meshesCount; i++) {
|
for (int i = 0; i < r.meshesCount; i++) {
|
||||||
Room::Mesh &m = r.meshes[i];
|
Room::Mesh &m = r.meshes[i];
|
||||||
stream.read(m.x);
|
stream.read(m.pos.x);
|
||||||
stream.read(m.y);
|
stream.read(m.pos.y);
|
||||||
stream.read(m.z);
|
stream.read(m.pos.z);
|
||||||
stream.read(m.rotation.value);
|
stream.read(m.rotation.value);
|
||||||
if (version & (VER_TR3 | VER_TR4)) {
|
if (version & (VER_TR3 | VER_TR4)) {
|
||||||
Color16 color;
|
Color16 color;
|
||||||
@@ -6646,15 +6673,11 @@ namespace TR {
|
|||||||
return room.sectors[sectorIndex = (x * room.zSectors + z)];
|
return room.sectors[sectorIndex = (x * room.zSectors + z)];
|
||||||
}
|
}
|
||||||
|
|
||||||
Room::Sector* getSector(int16 &roomIndex, const vec3 &pos) {
|
Room::Sector* getSector(int16 &roomIndex, int32 x, int32 y, int32 z) {
|
||||||
ASSERT(roomIndex >= 0 && roomIndex <= roomsCount);
|
ASSERT(roomIndex >= 0 && roomIndex <= roomsCount);
|
||||||
|
|
||||||
Room::Sector *sector = NULL;
|
Room::Sector *sector = NULL;
|
||||||
|
|
||||||
int x = int(pos.x);
|
|
||||||
int y = int(pos.y);
|
|
||||||
int z = int(pos.z);
|
|
||||||
|
|
||||||
// check horizontal
|
// check horizontal
|
||||||
int16 prevRoom = roomIndex;
|
int16 prevRoom = roomIndex;
|
||||||
|
|
||||||
@@ -6687,23 +6710,38 @@ namespace TR {
|
|||||||
return sector;
|
return sector;
|
||||||
}
|
}
|
||||||
|
|
||||||
float getFloor(const Room::Sector *sector, const vec3 &pos, int16 *roomIndex = NULL) {
|
Room::Sector* getSector(int16 &roomIndex, const vec3 &pos) {
|
||||||
int x = int(pos.x);
|
return getSector(roomIndex, int32(pos.x), int32(pos.y), int32(pos.z));
|
||||||
int z = int(pos.z);
|
}
|
||||||
|
|
||||||
|
int16 getFloor(const Room::Sector *sector, int32 x, int32 y, int32 z, SlantType *slantType = NULL, int16 *slant = NULL, int16 **trigger = NULL, int16 *roomIndex = NULL) {
|
||||||
int dx = x & 1023;
|
int dx = x & 1023;
|
||||||
int dz = z & 1023;
|
int dz = z & 1023;
|
||||||
|
|
||||||
|
if (slant) {
|
||||||
|
*slant = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slantType) {
|
||||||
|
*slantType = SLANT_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trigger) {
|
||||||
|
*trigger = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
while (sector->roomBelow != NO_ROOM) {
|
while (sector->roomBelow != NO_ROOM) {
|
||||||
Room &room = rooms[sector->roomBelow];
|
Room &room = rooms[sector->roomBelow];
|
||||||
if (roomIndex)
|
if (roomIndex) {
|
||||||
*roomIndex = sector->roomBelow;
|
*roomIndex = sector->roomBelow;
|
||||||
|
}
|
||||||
sector = room.getSector((x - room.info.x) / 1024, (z - room.info.z) / 1024);
|
sector = room.getSector((x - room.info.x) / 1024, (z - room.info.z) / 1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
int floor = sector->floor * 256;
|
int floor = sector->floor * 256;
|
||||||
|
|
||||||
if (!sector->floorIndex)
|
if (!sector->floorIndex)
|
||||||
return float(floor);
|
return floor;
|
||||||
|
|
||||||
FloorData *fd = &floors[sector->floorIndex];
|
FloorData *fd = &floors[sector->floorIndex];
|
||||||
FloorData::Command cmd;
|
FloorData::Command cmd;
|
||||||
@@ -6724,6 +6762,14 @@ namespace TR {
|
|||||||
if (cmd.func == TR::FloorData::FLOOR) {
|
if (cmd.func == TR::FloorData::FLOOR) {
|
||||||
sx = fd->slantX;
|
sx = fd->slantX;
|
||||||
sz = fd->slantZ;
|
sz = fd->slantZ;
|
||||||
|
|
||||||
|
if (slant) {
|
||||||
|
*slant = fd->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slantType) {
|
||||||
|
*slantType = (abs(sx) <= 2 && abs(sz) <= 2) ? SLANT_LOW : SLANT_HIGH;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (cmd.func == TR::FloorData::FLOOR_NW_SE_SOLID ||
|
if (cmd.func == TR::FloorData::FLOOR_NW_SE_SOLID ||
|
||||||
cmd.func == TR::FloorData::FLOOR_NW_SE_PORTAL_SE ||
|
cmd.func == TR::FloorData::FLOOR_NW_SE_PORTAL_SE ||
|
||||||
@@ -6757,6 +6803,9 @@ namespace TR {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case FloorData::TRIGGER : {
|
case FloorData::TRIGGER : {
|
||||||
|
if (trigger && *trigger == NULL) {
|
||||||
|
*trigger = (int16*)(fd - 1);
|
||||||
|
}
|
||||||
fd++;
|
fd++;
|
||||||
FloorData::TriggerCommand trigCmd;
|
FloorData::TriggerCommand trigCmd;
|
||||||
do {
|
do {
|
||||||
@@ -6772,12 +6821,10 @@ namespace TR {
|
|||||||
}
|
}
|
||||||
} while (!cmd.end);
|
} while (!cmd.end);
|
||||||
|
|
||||||
return float(floor);
|
return floor;
|
||||||
}
|
}
|
||||||
|
|
||||||
float getCeiling(const Room::Sector *sector, const vec3 &pos) {
|
int16 getCeiling(const Room::Sector *sector, int32 x, int32 y, int32 z) {
|
||||||
int x = int(pos.x);
|
|
||||||
int z = int(pos.z);
|
|
||||||
int dx = x & 1023;
|
int dx = x & 1023;
|
||||||
int dz = z & 1023;
|
int dz = z & 1023;
|
||||||
|
|
||||||
@@ -6790,7 +6837,7 @@ namespace TR {
|
|||||||
int ceiling = sector->ceiling * 256;
|
int ceiling = sector->ceiling * 256;
|
||||||
|
|
||||||
if (!sector->floorIndex)
|
if (!sector->floorIndex)
|
||||||
return float(ceiling);
|
return ceiling;
|
||||||
|
|
||||||
FloorData *fd = &floors[sector->floorIndex];
|
FloorData *fd = &floors[sector->floorIndex];
|
||||||
FloorData::Command cmd;
|
FloorData::Command cmd;
|
||||||
@@ -6859,13 +6906,18 @@ namespace TR {
|
|||||||
}
|
}
|
||||||
} while (!cmd.end);
|
} while (!cmd.end);
|
||||||
|
|
||||||
return float(ceiling);
|
return ceiling;
|
||||||
}
|
}
|
||||||
|
|
||||||
Room::Sector* getWaterLevelSector(int16 &roomIndex, const vec3 &pos) {
|
float getFloor(const Room::Sector *sector, const vec3 &pos, int16 *roomIndex = NULL) {
|
||||||
int x = int(pos.x);
|
return (float)getFloor(sector, int32(pos.x), int32(pos.y), int32(pos.z), NULL, NULL, NULL, roomIndex);
|
||||||
int z = int(pos.z);
|
}
|
||||||
|
|
||||||
|
float getCeiling(const Room::Sector *sector, const vec3 &pos, int16 *roomIndex = NULL) {
|
||||||
|
return (float)getCeiling(sector, int32(pos.x), int32(pos.y), int32(pos.z));
|
||||||
|
}
|
||||||
|
|
||||||
|
Room::Sector* getWaterLevelSector(int16 &roomIndex, int32 x, int32 z) {
|
||||||
Room *room = &rooms[roomIndex];
|
Room *room = &rooms[roomIndex];
|
||||||
Room::Sector *sector = room->getSector((x - room->info.x) / 1024, (z - room->info.z) / 1024);
|
Room::Sector *sector = room->getSector((x - room->info.x) / 1024, (z - room->info.z) / 1024);
|
||||||
|
|
||||||
@@ -6877,6 +6929,7 @@ namespace TR {
|
|||||||
roomIndex = sector->roomAbove;
|
roomIndex = sector->roomAbove;
|
||||||
sector = room->getSector((x - room->info.x) / 1024, (z - room->info.z) / 1024);
|
sector = room->getSector((x - room->info.x) / 1024, (z - room->info.z) / 1024);
|
||||||
}
|
}
|
||||||
|
return sector;
|
||||||
} else { // go down to the water
|
} else { // go down to the water
|
||||||
while (sector->roomBelow != NO_ROOM) {
|
while (sector->roomBelow != NO_ROOM) {
|
||||||
room = &rooms[roomIndex = sector->roomBelow];
|
room = &rooms[roomIndex = sector->roomBelow];
|
||||||
@@ -6884,9 +6937,13 @@ namespace TR {
|
|||||||
if (room->flags.water)
|
if (room->flags.water)
|
||||||
return sector;
|
return sector;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Room::Sector* getWaterLevelSector(int16 &roomIndex, const vec3 &pos) {
|
||||||
|
return getWaterLevelSector(roomIndex, int32(pos.x), int32(pos.z));
|
||||||
|
}
|
||||||
|
|
||||||
void getWaterInfo(int16 roomIndex, const vec3 &pos, float &level, float &depth) {
|
void getWaterInfo(int16 roomIndex, const vec3 &pos, float &level, float &depth) {
|
||||||
depth = 0.0f;
|
depth = 0.0f;
|
||||||
|
@@ -262,6 +262,10 @@ namespace Game {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (frameDelta > 30) { // maximum one sec frame drop
|
||||||
|
frameDelta = 30;
|
||||||
|
}
|
||||||
|
|
||||||
if (nextLevel) {
|
if (nextLevel) {
|
||||||
startLevel(nextLevel);
|
startLevel(nextLevel);
|
||||||
nextLevel = NULL;
|
nextLevel = NULL;
|
||||||
|
3816
src/lara.h
3816
src/lara.h
File diff suppressed because it is too large
Load Diff
@@ -358,9 +358,9 @@ struct MeshBuilder {
|
|||||||
if (!level->meshOffsets[s->mesh]) continue;
|
if (!level->meshOffsets[s->mesh]) continue;
|
||||||
TR::Mesh &mesh = level->meshes[level->meshOffsets[s->mesh]];
|
TR::Mesh &mesh = level->meshes[level->meshOffsets[s->mesh]];
|
||||||
|
|
||||||
int x = m.x - room.info.x;
|
int x = m.pos.x - room.info.x;
|
||||||
int y = m.y;
|
int y = m.pos.y;
|
||||||
int z = m.z - room.info.z;
|
int z = m.pos.z - room.info.z;
|
||||||
int d = m.rotation.value / 0x4000;
|
int d = m.rotation.value / 0x4000;
|
||||||
buildMesh(geom, blendMask, mesh, level, indices, vertices, iCount, vCount, vStartRoom, 0, x, y, z, d, m.color, true, false);
|
buildMesh(geom, blendMask, mesh, level, indices, vertices, iCount, vCount, vStartRoom, 0, x, y, z, d, m.color, true, false);
|
||||||
}
|
}
|
||||||
|
90
src/utils.h
90
src/utils.h
@@ -88,6 +88,14 @@
|
|||||||
#define SQR(x) ((x)*(x))
|
#define SQR(x) ((x)*(x))
|
||||||
#define randf() (float(rand())/float(RAND_MAX))
|
#define randf() (float(rand())/float(RAND_MAX))
|
||||||
|
|
||||||
|
// fixed point angles
|
||||||
|
#define DEG2SHORT (0x10000 / 360)
|
||||||
|
#define ANGLE_0 0
|
||||||
|
#define ANGLE_1 DEG2SHORT
|
||||||
|
#define ANGLE_45 0x2000 // != 45 * DEG2SHORT !!!
|
||||||
|
#define ANGLE_90 0x4000
|
||||||
|
#define ANGLE_180 0x8000
|
||||||
|
|
||||||
typedef signed char int8;
|
typedef signed char int8;
|
||||||
typedef signed short int16;
|
typedef signed short int16;
|
||||||
typedef signed int int32;
|
typedef signed int int32;
|
||||||
@@ -348,6 +356,24 @@ namespace Noise { // based on https://github.com/Auburns/FastNoise
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct vec3i {
|
||||||
|
int32 x, y, z;
|
||||||
|
|
||||||
|
inline vec3i() {}
|
||||||
|
inline vec3i(int s) : x(s), y(s), z(s) {}
|
||||||
|
inline vec3i(int32 x, int32 y, int32 z) : x(x), y(y), z(z) {}
|
||||||
|
|
||||||
|
inline vec3i operator + (const vec3i &v) const { return vec3i(x + v.x, y + v.y, z + v.z); }
|
||||||
|
inline vec3i operator - (const vec3i &v) const { return vec3i(x - v.x, y - v.y, z - v.z); }
|
||||||
|
|
||||||
|
inline vec3i operator * (int32 s) const { return vec3i(x * s, y * s, z * s); }
|
||||||
|
inline vec3i operator / (int32 s) const { return vec3i(x / s, y / s, z / s); }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct vec3s {
|
||||||
|
int16 x, y, z;
|
||||||
|
};
|
||||||
|
|
||||||
struct vec2 {
|
struct vec2 {
|
||||||
float x, y;
|
float x, y;
|
||||||
vec2() {}
|
vec2() {}
|
||||||
@@ -1225,17 +1251,6 @@ struct Box {
|
|||||||
return min;
|
return min;
|
||||||
}
|
}
|
||||||
|
|
||||||
Box intersection2D(const Box &b) const {
|
|
||||||
Box r(vec3(0.0f), vec3(0.0f));
|
|
||||||
if (max.x < b.min.x || min.x > b.max.x) return r;
|
|
||||||
if (max.y < b.min.y || min.y > b.max.y) return r;
|
|
||||||
r.max.x = ::min(max.x, b.max.x);
|
|
||||||
r.max.y = ::min(max.y, b.max.y);
|
|
||||||
r.min.x = ::max(min.x, b.min.x);
|
|
||||||
r.min.y = ::max(min.y, b.min.y);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
Box& operator += (const Box &box) {
|
Box& operator += (const Box &box) {
|
||||||
min.x = ::min(min.x, box.min.x);
|
min.x = ::min(min.x, box.min.x);
|
||||||
min.y = ::min(min.y, box.min.y);
|
min.y = ::min(min.y, box.min.y);
|
||||||
@@ -1384,6 +1399,59 @@ struct Box {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct BoxV2 {
|
||||||
|
vec3i min, max;
|
||||||
|
|
||||||
|
BoxV2() {}
|
||||||
|
BoxV2(const vec3i &min, const vec3i &max) : min(min), max(max) {}
|
||||||
|
|
||||||
|
bool intersect(const BoxV2 &box) const {
|
||||||
|
return !((max.x <= box.min.x || min.x >= box.max.x) || (max.y <= box.min.y || min.y >= box.max.y) || (max.z <= box.min.z || min.z >= box.max.z));
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3i center() const {
|
||||||
|
return (min + max) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3i size() const {
|
||||||
|
return max - min;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3i closestPoint(const vec3i &p) const {
|
||||||
|
return vec3i(clamp(p.x, min.x, max.x),
|
||||||
|
clamp(p.y, min.y, max.y),
|
||||||
|
clamp(p.z, min.z, max.z));
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3i pushOut2D(const BoxV2 &b) const {
|
||||||
|
int32 ax = b.max.x - min.x;
|
||||||
|
int32 bx = max.x - b.min.x;
|
||||||
|
int32 az = b.max.z - min.z;
|
||||||
|
int32 bz = max.z - b.min.z;
|
||||||
|
|
||||||
|
return vec3i(
|
||||||
|
(ax < bx) ? -ax : bx,
|
||||||
|
0,
|
||||||
|
(az < bz) ? -az : bz
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void translate(const vec3i &v) {
|
||||||
|
min = min + v;
|
||||||
|
max = max + v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rotate90(int n) {
|
||||||
|
switch (n) {
|
||||||
|
case 0 : break;
|
||||||
|
case 1 : *this = BoxV2(vec3i( min.z, min.y, -max.x), vec3i( max.z, max.y, -min.x)); break;
|
||||||
|
case 2 : *this = BoxV2(vec3i(-max.x, min.y, -max.z), vec3i(-min.x, max.y, -min.z)); break;
|
||||||
|
case 3 : *this = BoxV2(vec3i(-max.z, min.y, min.x), vec3i(-min.z, max.y, max.x)); break;
|
||||||
|
default : ASSERT(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
union Color32 { // RGBA8888
|
union Color32 { // RGBA8888
|
||||||
uint32 value;
|
uint32 value;
|
||||||
struct { uint8 r, g, b, a; };
|
struct { uint8 r, g, b, a; };
|
||||||
|
Reference in New Issue
Block a user