[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 index;
int/*bool*/rotate;
int degrees;
int/*bool*/flip;
int* splits;
int* pads;

View File

@ -51,6 +51,7 @@ struct spMeshAttachment {
int regionOriginalWidth, regionOriginalHeight; /* Unrotated, unstripped pixel size. */
float regionU, regionV, regionU2, regionV2;
int/*bool*/regionRotate;
int regionDegrees;
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);
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);
region->x = toInt(tuple);

View File

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

View File

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