[c] Ported rotated mesh region UV loading. See #1327.

This commit is contained in:
badlogic 2019-04-17 17:18:59 +02:00
parent 037802bb0c
commit 9a30520669
5 changed files with 56 additions and 15 deletions

View File

@ -123,6 +123,7 @@ struct spAtlasRegion {
int originalWidth, originalHeight; int originalWidth, originalHeight;
int index; int index;
int/*bool*/rotate; int/*bool*/rotate;
int degrees;
int/*bool*/flip; int/*bool*/flip;
int* splits; int* splits;
int* pads; int* pads;

View File

@ -51,6 +51,7 @@ struct spMeshAttachment {
int regionOriginalWidth, regionOriginalHeight; /* Unrotated, unstripped pixel size. */ int regionOriginalWidth, regionOriginalHeight; /* Unrotated, unstripped pixel size. */
float regionU, regionV, regionU2, regionV2; float regionU, regionV, regionU2, regionV2;
int/*bool*/regionRotate; int/*bool*/regionRotate;
int regionDegrees;
const char* path; const char* path;

View File

@ -246,7 +246,14 @@ spAtlas* spAtlas_create(const char* begin, int length, const char* dir, void* re
region->name = mallocString(&str); region->name = mallocString(&str);
if (!readValue(&begin, end, &str)) return abortAtlas(self); if (!readValue(&begin, end, &str)) return abortAtlas(self);
region->rotate = equals(&str, "true"); if (equals(&str, "true")) {
region->degrees = 90;
} else if (equals(&str, "false")) {
region->degrees = 0;
} else {
region->degrees = toInt(&str);
}
region->rotate = region->degrees == 90;
if (readTuple(&begin, end, tuple) != 2) return abortAtlas(self); if (readTuple(&begin, end, tuple) != 2) return abortAtlas(self);
region->x = toInt(tuple); region->x = toInt(tuple);

View File

@ -68,6 +68,7 @@ spAttachment* _spAtlasAttachmentLoader_createAttachment (spAttachmentLoader* loa
attachment->regionU2 = region->u2; attachment->regionU2 = region->u2;
attachment->regionV2 = region->v2; attachment->regionV2 = region->v2;
attachment->regionRotate = region->rotate; attachment->regionRotate = region->rotate;
attachment->regionDegrees = region->degrees;
attachment->regionOffsetX = region->offsetX; attachment->regionOffsetX = region->offsetX;
attachment->regionOffsetY = region->offsetY; attachment->regionOffsetY = region->offsetY;
attachment->regionWidth = region->width; attachment->regionWidth = region->width;

View File

@ -55,34 +55,65 @@ spMeshAttachment* spMeshAttachment_create (const char* name) {
void spMeshAttachment_updateUVs (spMeshAttachment* self) { void spMeshAttachment_updateUVs (spMeshAttachment* self) {
int i, n; int i, n;
float width, height;
int verticesLength = SUPER(self)->worldVerticesLength; int verticesLength = SUPER(self)->worldVerticesLength;
FREE(self->uvs); FREE(self->uvs);
self->uvs = MALLOC(float, verticesLength); float* uvs = self->uvs = MALLOC(float, verticesLength);
n = verticesLength;
float u = self->regionU, v = self->regionV;
float width = 0, height = 0;
if (self->regionRotate) { switch (self->regionDegrees) {
case 90: {
float textureWidth = self->regionHeight / (self->regionU2 - self->regionU); float textureWidth = self->regionHeight / (self->regionU2 - self->regionU);
float textureHeight = self->regionWidth / (self->regionV2 - self->regionV); float textureHeight = self->regionWidth / (self->regionV2 - self->regionV);
float u = self->regionU - (self->regionOriginalHeight - self->regionOffsetY - self->regionHeight) / textureWidth; u -= (self->regionOriginalHeight - self->regionOffsetY - self->regionHeight) / textureWidth;
float v = self->regionV - (self->regionOriginalWidth - self->regionOffsetX - self->regionWidth) / textureHeight; v -= (self->regionOriginalWidth - self->regionOffsetX - self->regionWidth) / textureHeight;
width = self->regionOriginalHeight / textureWidth; width = self->regionOriginalHeight / textureWidth;
height = self->regionOriginalWidth / textureHeight; height = self->regionOriginalWidth / textureHeight;
for (i = 0, n = verticesLength; i < n; i += 2) { for (i = 0; i < n; i += 2) {
self->uvs[i] = u + self->regionUVs[i + 1] * width; uvs[i] = u + self->regionUVs[i + 1] * width;
self->uvs[i + 1] = v + height - self->regionUVs[i] * height; uvs[i + 1] = v + (1 - self->regionUVs[i]) * height;
} }
return; return;
} else { }
case 180: {
float textureWidth = self->regionWidth / (self->regionU2 - self->regionU); float textureWidth = self->regionWidth / (self->regionU2 - self->regionU);
float textureHeight = self->regionHeight / (self->regionV2 - self->regionV); float textureHeight = self->regionHeight / (self->regionV2 - self->regionV);
float u = self->regionU - self->regionOffsetX / textureWidth; u -= (self->regionOriginalWidth - self->regionOffsetX - self->regionWidth) / textureWidth;
float v = self->regionV - (self->regionOriginalHeight - self->regionOffsetY - self->regionHeight) / textureHeight; v -= self->regionOffsetY / textureHeight;
width = self->regionOriginalWidth / textureWidth; width = self->regionOriginalWidth / textureWidth;
height = self->regionOriginalHeight / textureHeight; height = self->regionOriginalHeight / textureHeight;
for (i = 0, n = verticesLength; i < n; i += 2) { for (i = 0; i < n; i += 2) {
self->uvs[i] = u + self->regionUVs[i] * width; uvs[i] = u + (1 - self->regionUVs[i]) * width;
self->uvs[i + 1] = v + self->regionUVs[i + 1] * height; uvs[i + 1] = v + (1 - self->regionUVs[i + 1]) * height;
} }
return;
}
case 270: {
float textureHeight = self->regionHeight / (self->regionV2 - self->regionV);
float textureWidth = self->regionWidth / (self->regionU2 - self->regionU);
u -= self->regionOffsetY / textureWidth;
v -= self->regionOffsetX / textureHeight;
width = self->regionOriginalHeight / textureWidth;
height = self->regionOriginalWidth / textureHeight;
for (i = 0; i < n; i += 2) {
uvs[i] = u + (1 - self->regionUVs[i + 1]) * width;
uvs[i + 1] = v + self->regionUVs[i] * height;
}
return;
}
default: {
float textureWidth = self->regionWidth / (self->regionU2 - self->regionU);
float textureHeight = self->regionHeight / (self->regionV2 - self->regionV);
u -= self->regionOffsetX / textureWidth;
v -= (self->regionOriginalHeight - self->regionOffsetY - self->regionHeight) / textureHeight;
width = self->regionOriginalWidth / textureWidth;
height = self->regionOriginalHeight / textureHeight;
for (i = 0; i < n; i += 2) {
uvs[i] = u + self->regionUVs[i] * width;
uvs[i + 1] = v + self->regionUVs[i + 1] * height;
}
}
} }
} }