Compare commits

...

2 Commits

Author SHA1 Message Date
bjorn f4d5c0d758 Add assert for body count; 2024-04-06 00:47:31 -07:00
bjorn 38a68dc4e5 TerrainShape image must be square; 2024-04-06 00:12:50 -07:00
4 changed files with 30 additions and 30 deletions

View File

@ -91,17 +91,17 @@ Shape* luax_newmeshshape(lua_State* L, int index) {
}
Shape* luax_newterrainshape(lua_State* L, int index) {
float horizontalScale = luax_checkfloat(L, index++);
float scaleXZ = luax_checkfloat(L, index++);
int type = lua_type(L, index);
if (type == LUA_TNIL || type == LUA_TNONE) {
float vertices[4] = { 0.f };
return lovrTerrainShapeCreate(vertices, 2, 2, horizontalScale, 1.f);
return lovrTerrainShapeCreate(vertices, 2, scaleXZ, 1.f);
} else if (type == LUA_TFUNCTION) {
uint32_t samples = luax_optu32(L, index + 1, 100);
float* vertices = lovrMalloc(sizeof(float) * samples * samples);
for (uint32_t i = 0; i < samples * samples; i++) {
float x = horizontalScale * (-.5f + ((float) (i % samples)) / samples);
float z = horizontalScale * (-.5f + ((float) (i / samples)) / samples);
uint32_t n = luax_optu32(L, index + 1, 100);
float* vertices = lovrMalloc(sizeof(float) * n * n);
for (uint32_t i = 0; i < n * n; i++) {
float x = scaleXZ * (-.5f + ((float) (i % n)) / n);
float z = scaleXZ * (-.5f + ((float) (i / n)) / n);
lua_pushvalue(L, index);
lua_pushnumber(L, x);
lua_pushnumber(L, z);
@ -110,23 +110,23 @@ Shape* luax_newterrainshape(lua_State* L, int index) {
vertices[i] = luax_tofloat(L, -1);
lua_pop(L, 1);
}
TerrainShape* shape = lovrTerrainShapeCreate(vertices, samples, samples, horizontalScale, 1.f);
TerrainShape* shape = lovrTerrainShapeCreate(vertices, n, scaleXZ, 1.f);
lovrFree(vertices);
return shape;
} else if (type == LUA_TUSERDATA) {
Image* image = luax_checktype(L, index, Image);
uint32_t imageWidth = lovrImageGetWidth(image, 0);
uint32_t imageHeight = lovrImageGetHeight(image, 0);
float verticalScale = luax_optfloat(L, index + 1, 1.f);
float* vertices = lovrMalloc(sizeof(float) * imageWidth * imageHeight);
for (uint32_t y = 0; y < imageHeight; y++) {
for (uint32_t x = 0; x < imageWidth; x++) {
uint32_t n = lovrImageGetWidth(image, 0);
lovrCheck(lovrImageGetHeight(image, 0) == n, "TerrainShape images must be square");
float scaleY = luax_optfloat(L, index + 1, 1.f);
float* vertices = lovrMalloc(sizeof(float) * n * n);
for (uint32_t y = 0; y < n; y++) {
for (uint32_t x = 0; x < n; x++) {
float pixel[4];
lovrImageGetPixel(image, x, y, pixel);
vertices[x + y * imageWidth] = pixel[0];
vertices[x + y * n] = pixel[0];
}
}
TerrainShape* shape = lovrTerrainShapeCreate(vertices, imageWidth, imageHeight, horizontalScale, verticalScale);
TerrainShape* shape = lovrTerrainShapeCreate(vertices, n, scaleXZ, scaleY);
lovrFree(vertices);
return shape;
} else {

View File

@ -191,7 +191,7 @@ void lovrCylinderShapeSetLength(CylinderShape* cylinder, float length);
MeshShape* lovrMeshShapeCreate(int vertexCount, float vertices[], int indexCount, uint32_t indices[]);
TerrainShape* lovrTerrainShapeCreate(float* vertices, uint32_t widthSamples, uint32_t depthSamples, float horizontalScale, float verticalScale);
TerrainShape* lovrTerrainShapeCreate(float* vertices, uint32_t n, float scaleXZ, float scaleY);
// These tokens need to exist for Lua bindings
#define lovrSphereShapeDestroy lovrShapeDestroy

View File

@ -316,7 +316,10 @@ void lovrWorldSetAngularDamping(World* world, float damping, float threshold) {
// Collider
Collider* lovrColliderCreate(World* world, float x, float y, float z) {
// todo: crashes when too many are added
uint32_t count = JPH_PhysicsSystem_GetNumBodies(world->system);
uint32_t limit = JPH_PhysicsSystem_GetMaxBodies(world->system);
lovrCheck(count < limit, "Too many colliders!");
Collider* collider = lovrCalloc(sizeof(Collider));
collider->ref = 1;
collider->world = world;
@ -956,24 +959,22 @@ MeshShape* lovrMeshShapeCreate(int vertexCount, float vertices[], int indexCount
return mesh;
}
TerrainShape* lovrTerrainShapeCreate(float* vertices, uint32_t widthSamples, uint32_t depthSamples, float horizontalScale, float verticalScale) {
lovrCheck(widthSamples == depthSamples, "Jolt needs terrain width and depth to be the same");
TerrainShape* lovrTerrainShapeCreate(float* vertices, uint32_t n, float scaleXZ, float scaleY) {
TerrainShape* terrain = lovrCalloc(sizeof(TerrainShape));
terrain->ref = 1;
terrain->type = SHAPE_TERRAIN;
const JPH_Vec3 offset = {
.x = -.5f * horizontalScale,
.x = -.5f * scaleXZ,
.y = 0.f,
.z = -.5f * horizontalScale
.z = -.5f * scaleXZ
};
const JPH_Vec3 scale = {
.x = horizontalScale / widthSamples,
.y = verticalScale,
.z = horizontalScale / depthSamples
.x = scaleXZ / n,
.y = scaleY,
.z = scaleXZ / n
};
JPH_HeightFieldShapeSettings* shape_settings = JPH_HeightFieldShapeSettings_Create(
vertices, &offset, &scale, widthSamples);
JPH_HeightFieldShapeSettings* shape_settings = JPH_HeightFieldShapeSettings_Create(vertices, &offset, &scale, n);
terrain->shape = (JPH_Shape*) JPH_HeightFieldShapeSettings_CreateShape(shape_settings);
JPH_ShapeSettings_Destroy((JPH_ShapeSettings*) shape_settings);
return terrain;

View File

@ -1119,13 +1119,12 @@ MeshShape* lovrMeshShapeCreate(int vertexCount, float* vertices, int indexCount,
return mesh;
}
TerrainShape* lovrTerrainShapeCreate(float* vertices, uint32_t widthSamples, uint32_t depthSamples, float horizontalScale, float verticalScale) {
TerrainShape* lovrTerrainShapeCreate(float* vertices, uint32_t n, float scaleXZ, float scaleY) {
const float thickness = 10.f;
TerrainShape* terrain = lovrCalloc(sizeof(TerrainShape));
terrain->ref = 1;
dHeightfieldDataID dataID = dGeomHeightfieldDataCreate();
dGeomHeightfieldDataBuildSingle(dataID, vertices, 1, horizontalScale, horizontalScale,
widthSamples, depthSamples, verticalScale, 0.f, thickness, 0);
dGeomHeightfieldDataBuildSingle(dataID, vertices, 1, scaleXZ, scaleXZ, n, n, scaleY, 0.f, thickness, 0);
terrain->id = dCreateHeightfield(0, dataID, 1);
terrain->type = SHAPE_TERRAIN;
dGeomSetData(terrain->id, terrain);