Fix lovr.headset.newModel and lovr.headset.animate;

This commit is contained in:
bjorn 2022-08-06 00:29:46 -07:00
parent dd40e6c829
commit 6011e61d52
4 changed files with 109 additions and 67 deletions

View File

@ -488,12 +488,37 @@ static int l_lovrHeadsetVibrate(lua_State* L) {
}
static int l_lovrHeadsetNewModel(lua_State* L) {
lua_pushnil(L); // TODO
return 1;
Device device = luax_optdevice(L, 1);
bool animated = false;
if (lua_istable(L, 2)) {
lua_getfield(L, 2, "animated");
animated = lua_toboolean(L, -1);
lua_pop(L, 1);
}
ModelData* modelData = lovrHeadsetInterface->newModelData(device, animated);
if (modelData) {
ModelInfo info = { .data = modelData, .mipmaps = true };
Model* model = lovrModelCreate(&info);
luax_pushtype(L, Model, model);
lovrRelease(modelData, lovrModelDataDestroy);
lovrRelease(model, lovrModelDestroy);
return 1;
}
return 0;
}
static int l_lovrHeadsetAnimate(lua_State* L) {
lua_pushboolean(L, false); // TODO
Device device = luax_optdevice(L, 1);
Model* model = luax_checktype(L, 2, Model);
if (lovrHeadsetInterface->animate(device, model)) {
lua_pushboolean(L, true);
return 1;
}
lua_pushboolean(L, false);
return 1;
}

View File

@ -29,65 +29,9 @@ ModelData* lovrModelDataCreate(Blob* source, ModelDataIO* io) {
}
}
// Precomputed properties and validation
lovrModelDataFinalize(model);
for (uint32_t i = 0; i < model->primitiveCount; i++) {
model->primitives[i].skin = 0xaaaaaaaa;
}
for (uint32_t i = 0; i < model->nodeCount; i++) {
ModelNode* node = &model->nodes[i];
for (uint32_t j = 0, index = node->primitiveIndex; j < node->primitiveCount; j++, index++) {
if (model->primitives[index].skin != 0xaaaaaaaa) {
lovrCheck(model->primitives[index].skin == node->skin, "Model has a mesh used with multiple skins, which is not supported");
} else {
model->primitives[index].skin = node->skin;
}
}
}
model->indexType = U16;
for (uint32_t i = 0; i < model->primitiveCount; i++) {
ModelPrimitive* primitive = &model->primitives[i];
uint32_t vertexCount = primitive->attributes[ATTR_POSITION]->count;
if (primitive->skin != ~0u) {
model->skins[primitive->skin].vertexCount += vertexCount;
model->skinnedVertexCount += vertexCount;
}
model->vertexCount += vertexCount;
model->indexCount += primitive->indices ? primitive->indices->count : 0;
if (primitive->indices) {
if (primitive->indices->type == U32) {
primitive->indices->stride = 4;
model->indexType = U32;
} else {
primitive->indices->stride = 2;
}
}
for (uint32_t i = 0; i < MAX_DEFAULT_ATTRIBUTES; i++) {
ModelAttribute* attribute = primitive->attributes[i];
if (attribute) {
attribute->stride = model->buffers[attribute->buffer].stride;
if (attribute->stride == 0) {
attribute->stride = typeSizes[attribute->type] * attribute->components;
}
}
}
}
for (uint32_t i = 0; i < model->nodeCount; i++) {
model->nodes[i].parent = ~0u;
}
for (uint32_t i = 0; i < model->nodeCount; i++) {
ModelNode* node = &model->nodes[i];
for (uint32_t j = 0; j < node->childCount; j++) {
model->nodes[node->children[j]].parent = i;
}
}
return model;
return model;
}
@ -151,6 +95,66 @@ void lovrModelDataAllocate(ModelData* model) {
map_init(&model->nodeMap, model->nodeCount);
}
void lovrModelDataFinalize(ModelData* model) {
for (uint32_t i = 0; i < model->primitiveCount; i++) {
model->primitives[i].skin = 0xaaaaaaaa;
}
for (uint32_t i = 0; i < model->nodeCount; i++) {
ModelNode* node = &model->nodes[i];
for (uint32_t j = 0, index = node->primitiveIndex; j < node->primitiveCount; j++, index++) {
if (model->primitives[index].skin != 0xaaaaaaaa) {
lovrCheck(model->primitives[index].skin == node->skin, "Model has a mesh used with multiple skins, which is not supported");
} else {
model->primitives[index].skin = node->skin;
}
}
}
model->indexType = U16;
for (uint32_t i = 0; i < model->primitiveCount; i++) {
ModelPrimitive* primitive = &model->primitives[i];
uint32_t vertexCount = primitive->attributes[ATTR_POSITION]->count;
if (primitive->skin != ~0u) {
model->skins[primitive->skin].vertexCount += vertexCount;
model->skinnedVertexCount += vertexCount;
}
model->vertexCount += vertexCount;
model->indexCount += primitive->indices ? primitive->indices->count : 0;
if (primitive->indices) {
if (primitive->indices->type == U32) {
primitive->indices->stride = 4;
model->indexType = U32;
} else {
primitive->indices->stride = 2;
}
}
for (uint32_t i = 0; i < MAX_DEFAULT_ATTRIBUTES; i++) {
ModelAttribute* attribute = primitive->attributes[i];
if (attribute) {
attribute->stride = model->buffers[attribute->buffer].stride;
if (attribute->stride == 0) {
attribute->stride = typeSizes[attribute->type] * attribute->components;
}
}
}
}
for (uint32_t i = 0; i < model->nodeCount; i++) {
model->nodes[i].parent = ~0u;
}
for (uint32_t i = 0; i < model->nodeCount; i++) {
ModelNode* node = &model->nodes[i];
for (uint32_t j = 0; j < node->childCount; j++) {
model->nodes[node->children[j]].parent = i;
}
}
}
void lovrModelDataCopyAttribute(ModelData* data, ModelAttribute* attribute, char* dst, AttributeType type, uint32_t components, bool normalized, uint32_t count, size_t stride, uint8_t clear) {
char* src = attribute ? data->buffers[attribute->buffer].data + attribute->offset : NULL;
size_t size = components * typeSizes[type];
@ -195,6 +199,12 @@ void lovrModelDataCopyAttribute(ModelData* data, ModelAttribute* attribute, char
((uint8_t*) dst)[j] = (uint8_t) ((uint16_t*) src)[j];
}
}
} else if (attribute->type == I16 && !attribute->normalized && !normalized) {
for (uint32_t i = 0; i < count; i++, src += attribute->stride, dst += stride) {
for (uint32_t j = 0; j < components; j++) {
((uint8_t*) dst)[j] = (uint8_t) ((int16_t*) src)[j];
}
}
} else if (attribute->type == F32 && normalized) {
for (uint32_t i = 0; i < count; i++, src += attribute->stride, dst += stride) {
for (uint32_t j = 0; j < components; j++) {

View File

@ -215,6 +215,7 @@ ModelData* lovrModelDataInitObj(ModelData* model, struct Blob* blob, ModelDataIO
ModelData* lovrModelDataInitStl(ModelData* model, struct Blob* blob, ModelDataIO* io);
void lovrModelDataDestroy(void* ref);
void lovrModelDataAllocate(ModelData* model);
void lovrModelDataFinalize(ModelData* model);
void lovrModelDataCopyAttribute(ModelData* data, ModelAttribute* attribute, char* dst, AttributeType type, uint32_t components, bool normalized, uint32_t count, size_t stride, uint8_t clear);
void lovrModelDataGetBoundingBox(ModelData* data, float box[6]);
void lovrModelDataGetBoundingSphere(ModelData* data, float sphere[4]);

View File

@ -1430,7 +1430,7 @@ static ModelData* openxr_newModelData(Device device, bool animated) {
mesh.vertexBlendWeights = (XrVector4f*) (meshData + offset), offset += sizes[7];
mesh.indices = (int16_t*) (meshData + offset), offset += sizes[8];
float* inverseBindMatrices = (float*) (meshData + offset); offset += sizes[9];
lovrAssert(offset == totalSize, "Unreachable");
lovrAssert(offset == totalSize, "Unreachable!");
result = xrGetHandMeshFB(tracker, &mesh);
if (XR_FAILED(result)) {
@ -1495,7 +1495,7 @@ static ModelData* openxr_newModelData(Device device, bool animated) {
.stride = sizeof(mesh.indices[0])
};
model->attributes[0] = (ModelAttribute) { .buffer = 0, .type = F32, .components = 3 };
model->attributes[0] = (ModelAttribute) { .buffer = 0, .type = F32, .components = 3, .count = vertexCount };
model->attributes[1] = (ModelAttribute) { .buffer = 1, .type = F32, .components = 3 };
model->attributes[2] = (ModelAttribute) { .buffer = 2, .type = F32, .components = 2 };
model->attributes[3] = (ModelAttribute) { .buffer = 3, .type = I16, .components = 4 };
@ -1574,6 +1574,8 @@ static ModelData* openxr_newModelData(Device device, bool animated) {
*children++ = XR_HAND_JOINT_WRIST_EXT;
*children++ = model->jointCount;
lovrModelDataFinalize(model);
return model;
}
@ -1634,11 +1636,12 @@ static bool openxr_animate(Device device, Model* model) {
XR_HAND_JOINT_LITTLE_DISTAL_EXT
};
float scale[4] = { 1.f, 1.f, 1.f, 1.f };
// The following can be optimized a lot (ideally we would set the global transform for the nodes)
for (uint32_t i = 0; i < COUNTOF(joints); i++) {
if (jointParents[i] == ~0u) {
float position[4] = { 0.f, 0.f, 0.f };
float scale[4] = { 1.f, 1.f, 1.f, 1.f };
float orientation[4] = { 0.f, 0.f, 0.f, 1.f };
lovrModelSetNodeTransform(model, i, position, scale, orientation, 1.f);
} else {
@ -1657,8 +1660,6 @@ static bool openxr_animate(Device device, Model* model) {
quat_rotate(orientation, position);
quat_mul(orientation, orientation, &pose->orientation.x);
float scale[4] = { 1.f, 1.f, 1.f, 1.f };
lovrModelSetNodeTransform(model, i, position, scale, orientation, 1.f);
}
}
@ -1667,6 +1668,10 @@ static bool openxr_animate(Device device, Model* model) {
}
static Texture* openxr_getTexture(void) {
if (!SESSION_ACTIVE(state.sessionState)) {
return NULL;
}
if (state.began) {
return state.frameState.shouldRender ? state.textures[state.textureIndex] : NULL;
}
@ -1697,7 +1702,8 @@ static Pass* openxr_getPass(void) {
return NULL;
}
float color[4][4], depth, stencil;
uint8_t stencil;
float color[4][4], depth;
lovrPassGetClear(state.pass, color, &depth, &stencil);
lovrGraphicsGetBackground(color[0]);
lovrPassSetClear(state.pass, color, depth, stencil);