mirror of
https://github.com/Garhoogin/NitroPaint.git
synced 2025-06-18 22:35:31 -04:00
Correct cell transformations without rotate/scale
OBJ positions are now transformed appropriately
This commit is contained in:
parent
13351c005e
commit
458f9c74f3
@ -1021,6 +1021,9 @@ static void AnmViewerPausePlayback(NANRVIEWERDATA *data) {
|
|||||||
static void AnmViewerStopPlayback(NANRVIEWERDATA *data) {
|
static void AnmViewerStopPlayback(NANRVIEWERDATA *data) {
|
||||||
AnmViewerPausePlayback(data);
|
AnmViewerPausePlayback(data);
|
||||||
data->resetFlag = 1; // set the reset flag
|
data->resetFlag = 1; // set the reset flag
|
||||||
|
|
||||||
|
//set anchor
|
||||||
|
AnmViewerSetDefaultAnchor(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AnmViewerAdvanceSequence(NANRVIEWERDATA *data) {
|
static void AnmViewerAdvanceSequence(NANRVIEWERDATA *data) {
|
||||||
@ -1573,7 +1576,7 @@ static void AnmViewerPreviewOnPaint(NANRVIEWERDATA *data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//render bounds
|
//render bounds
|
||||||
if (cell != NULL) {
|
if (cell != NULL && !data->playing) {
|
||||||
int boxX, boxY, boxW, boxH;
|
int boxX, boxY, boxW, boxH;
|
||||||
AnmViewerGetCellBounds(cell, &boxX, &boxY, &boxW, &boxH);
|
AnmViewerGetCellBounds(cell, &boxX, &boxY, &boxW, &boxH);
|
||||||
|
|
||||||
@ -2098,6 +2101,12 @@ static LRESULT CALLBACK AnmViewerFrameListSubclassProc(HWND hWnd, UINT msg, WPAR
|
|||||||
|
|
||||||
// ----- frame list procedures
|
// ----- frame list procedures
|
||||||
|
|
||||||
|
static void AnmViewerPutCurrentAnimFrameResetAnchor(NANRVIEWERDATA *data, const ANIM_DATA_SRT *srt, const int *pDuration) {
|
||||||
|
AnmViewerPutCurrentAnimFrame(data, srt, pDuration);
|
||||||
|
AnmViewerSetDefaultAnchor(data);
|
||||||
|
InvalidateRect(data->hWndAnimList, NULL, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
static void AnmViewerCmdSetIndex(NANRVIEWERDATA *data) {
|
static void AnmViewerCmdSetIndex(NANRVIEWERDATA *data) {
|
||||||
WCHAR buf[16] = { 0 };
|
WCHAR buf[16] = { 0 };
|
||||||
ANIM_DATA_SRT srt;
|
ANIM_DATA_SRT srt;
|
||||||
@ -2106,7 +2115,7 @@ static void AnmViewerCmdSetIndex(NANRVIEWERDATA *data) {
|
|||||||
|
|
||||||
PromptUserText(data->hWnd, L"Cell Index", L"Cell Index:", buf, sizeof(buf) / sizeof(buf[0]));
|
PromptUserText(data->hWnd, L"Cell Index", L"Cell Index:", buf, sizeof(buf) / sizeof(buf[0]));
|
||||||
srt.index = (unsigned short) _wtol(buf);
|
srt.index = (unsigned short) _wtol(buf);
|
||||||
AnmViewerPutCurrentAnimFrame(data, &srt, NULL);
|
AnmViewerPutCurrentAnimFrameResetAnchor(data, &srt, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AnmViewerCmdSetDuration(NANRVIEWERDATA *data) {
|
static void AnmViewerCmdSetDuration(NANRVIEWERDATA *data) {
|
||||||
@ -2117,7 +2126,7 @@ static void AnmViewerCmdSetDuration(NANRVIEWERDATA *data) {
|
|||||||
|
|
||||||
PromptUserText(data->hWnd, L"Enter Duration", L"Duration:", buf, sizeof(buf) / sizeof(buf[0]));
|
PromptUserText(data->hWnd, L"Enter Duration", L"Duration:", buf, sizeof(buf) / sizeof(buf[0]));
|
||||||
duration = _wtol(buf);
|
duration = _wtol(buf);
|
||||||
AnmViewerPutCurrentAnimFrame(data, NULL, &duration);
|
AnmViewerPutCurrentAnimFrameResetAnchor(data, NULL, &duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AnmViewerCmdSetX(NANRVIEWERDATA *data) {
|
static void AnmViewerCmdSetX(NANRVIEWERDATA *data) {
|
||||||
@ -2128,7 +2137,7 @@ static void AnmViewerCmdSetX(NANRVIEWERDATA *data) {
|
|||||||
|
|
||||||
PromptUserText(data->hWnd, L"Enter X Translation", L"X:", buf, sizeof(buf) / sizeof(buf[0]));
|
PromptUserText(data->hWnd, L"Enter X Translation", L"X:", buf, sizeof(buf) / sizeof(buf[0]));
|
||||||
srt.px = (short) _wtol(buf);
|
srt.px = (short) _wtol(buf);
|
||||||
AnmViewerPutCurrentAnimFrame(data, &srt, NULL);
|
AnmViewerPutCurrentAnimFrameResetAnchor(data, &srt, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AnmViewerCmdSetY(NANRVIEWERDATA *data) {
|
static void AnmViewerCmdSetY(NANRVIEWERDATA *data) {
|
||||||
@ -2139,7 +2148,7 @@ static void AnmViewerCmdSetY(NANRVIEWERDATA *data) {
|
|||||||
|
|
||||||
PromptUserText(data->hWnd, L"Enter Y Translation", L"Y:", buf, sizeof(buf) / sizeof(buf[0]));
|
PromptUserText(data->hWnd, L"Enter Y Translation", L"Y:", buf, sizeof(buf) / sizeof(buf[0]));
|
||||||
srt.py = (short) _wtol(buf);
|
srt.py = (short) _wtol(buf);
|
||||||
AnmViewerPutCurrentAnimFrame(data, &srt, NULL);
|
AnmViewerPutCurrentAnimFrameResetAnchor(data, &srt, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AnmViewerCmdSetScaleX(NANRVIEWERDATA *data) {
|
static void AnmViewerCmdSetScaleX(NANRVIEWERDATA *data) {
|
||||||
@ -2150,7 +2159,7 @@ static void AnmViewerCmdSetScaleX(NANRVIEWERDATA *data) {
|
|||||||
|
|
||||||
PromptUserText(data->hWnd, L"Enter X Scale", L"X:", buf, sizeof(buf) / sizeof(buf[0]));
|
PromptUserText(data->hWnd, L"Enter X Scale", L"X:", buf, sizeof(buf) / sizeof(buf[0]));
|
||||||
srt.sx = FloatToInt(my_wtof(buf) * 4096.0f);
|
srt.sx = FloatToInt(my_wtof(buf) * 4096.0f);
|
||||||
AnmViewerPutCurrentAnimFrame(data, &srt, NULL);
|
AnmViewerPutCurrentAnimFrameResetAnchor(data, &srt, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AnmViewerCmdSetScaleY(NANRVIEWERDATA *data) {
|
static void AnmViewerCmdSetScaleY(NANRVIEWERDATA *data) {
|
||||||
@ -2161,7 +2170,7 @@ static void AnmViewerCmdSetScaleY(NANRVIEWERDATA *data) {
|
|||||||
|
|
||||||
PromptUserText(data->hWnd, L"Enter Y Scale", L"Y:", buf, sizeof(buf) / sizeof(buf[0]));
|
PromptUserText(data->hWnd, L"Enter Y Scale", L"Y:", buf, sizeof(buf) / sizeof(buf[0]));
|
||||||
srt.sy = FloatToInt(my_wtof(buf) * 4096.0f);
|
srt.sy = FloatToInt(my_wtof(buf) * 4096.0f);
|
||||||
AnmViewerPutCurrentAnimFrame(data, &srt, NULL);
|
AnmViewerPutCurrentAnimFrameResetAnchor(data, &srt, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AnmViewerCmdSetRotation(NANRVIEWERDATA *data) {
|
static void AnmViewerCmdSetRotation(NANRVIEWERDATA *data) {
|
||||||
@ -2172,7 +2181,7 @@ static void AnmViewerCmdSetRotation(NANRVIEWERDATA *data) {
|
|||||||
|
|
||||||
PromptUserText(data->hWnd, L"Enter Rotation", L"Rotation:", buf, sizeof(buf) / sizeof(buf[0]));
|
PromptUserText(data->hWnd, L"Enter Rotation", L"Rotation:", buf, sizeof(buf) / sizeof(buf[0]));
|
||||||
srt.rotZ = FloatToInt(my_wtof(buf) * 65536.0f / 360.0f) & 0xFFFF;
|
srt.rotZ = FloatToInt(my_wtof(buf) * 65536.0f / 360.0f) & 0xFFFF;
|
||||||
AnmViewerPutCurrentAnimFrame(data, &srt, NULL);
|
AnmViewerPutCurrentAnimFrameResetAnchor(data, &srt, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AnmViewerInsertFrame(NANRVIEWERDATA *data, int i) {
|
static void AnmViewerInsertFrame(NANRVIEWERDATA *data, int i) {
|
||||||
@ -2199,6 +2208,7 @@ static void AnmViewerInsertFrame(NANRVIEWERDATA *data, int i) {
|
|||||||
AnmViewerPutCurrentAnimFrame(data, &frm, NULL);
|
AnmViewerPutCurrentAnimFrame(data, &frm, NULL);
|
||||||
data->currentFrame = oldI;
|
data->currentFrame = oldI;
|
||||||
AnmViewerSetCurrentFrame(data, i, TRUE);
|
AnmViewerSetCurrentFrame(data, i, TRUE);
|
||||||
|
AnmViewerSetDefaultAnchor(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AnmViewerCmdInsertFrameAbove(NANRVIEWERDATA *data) {
|
static void AnmViewerCmdInsertFrameAbove(NANRVIEWERDATA *data) {
|
||||||
@ -2247,6 +2257,8 @@ static void AnmViewerCmdInterpolateBelow(NANRVIEWERDATA *data) {
|
|||||||
AnmViewerPutCurrentAnimFrame(data, &setting.result[i], NULL);
|
AnmViewerPutCurrentAnimFrame(data, &setting.result[i], NULL);
|
||||||
}
|
}
|
||||||
AnmViewerSetCurrentFrame(data, frame0, TRUE);
|
AnmViewerSetCurrentFrame(data, frame0, TRUE);
|
||||||
|
AnmViewerSetDefaultAnchor(data);
|
||||||
|
InvalidateRect(data->hWndAnimList, NULL, FALSE);
|
||||||
|
|
||||||
free(setting.result);
|
free(setting.result);
|
||||||
free(setting.durations);
|
free(setting.durations);
|
||||||
|
@ -1040,6 +1040,7 @@ void CellViewerRenderCell(
|
|||||||
|
|
||||||
//compute inverse matrix parameters.
|
//compute inverse matrix parameters.
|
||||||
double invA = 1.0, invB = 0.0, invC = 0.0, invD = 1.0;
|
double invA = 1.0, invB = 0.0, invC = 0.0, invD = 1.0;
|
||||||
|
int isMtxIdentity = 1;
|
||||||
if (a != 1.0 || b != 0.0 || c != 0.0 || d != 1.0) {
|
if (a != 1.0 || b != 0.0 || c != 0.0 || d != 1.0) {
|
||||||
//not identity matrix
|
//not identity matrix
|
||||||
double det = a * d - b * c; // DBCA
|
double det = a * d - b * c; // DBCA
|
||||||
@ -1055,6 +1056,7 @@ void CellViewerRenderCell(
|
|||||||
invC = 0.0;
|
invC = 0.0;
|
||||||
invD = 127.99609375;
|
invD = 127.99609375;
|
||||||
}
|
}
|
||||||
|
isMtxIdentity = 0; // not identity
|
||||||
}
|
}
|
||||||
|
|
||||||
COLOR32 *block = (COLOR32 *) calloc(64 * 64, sizeof(COLOR32));
|
COLOR32 *block = (COLOR32 *) calloc(64 * 64, sizeof(COLOR32));
|
||||||
@ -1089,8 +1091,24 @@ void CellViewerRenderCell(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//apply transformation matrix to OBJ position
|
||||||
int x = info.x;
|
int x = info.x;
|
||||||
int y = info.y;
|
int y = info.y;
|
||||||
|
if (!isMtxIdentity) {
|
||||||
|
//adjust sign of OBJ coordinates, since we rely on signed coordinates
|
||||||
|
if (x >= 256) x -= 512;
|
||||||
|
if (y >= 128) y -= 256;
|
||||||
|
|
||||||
|
//adjust coordinates by correction for double-size
|
||||||
|
int realWidth = info.width << info.doubleSize;
|
||||||
|
int realHeight = info.height << info.doubleSize;
|
||||||
|
int movedX = x + realWidth / 2;
|
||||||
|
int movedY = y + realHeight / 2;
|
||||||
|
|
||||||
|
//un-correct moved position from center to top-left, un-correct for double-size
|
||||||
|
x = FloatToInt(movedX * a + movedY * b) - realWidth / 2;
|
||||||
|
y = FloatToInt(movedX * c + movedY * d) - realHeight / 2;
|
||||||
|
}
|
||||||
|
|
||||||
//copy data
|
//copy data
|
||||||
if (!info.rotateScale) {
|
if (!info.rotateScale) {
|
||||||
@ -1113,30 +1131,16 @@ void CellViewerRenderCell(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//adjust sign of OBJ coordinates, since we rely on signed coordinates
|
|
||||||
if (x >= 256) x -= 512;
|
|
||||||
if (y >= 128) y -= 256;
|
|
||||||
|
|
||||||
//transform about center
|
//transform about center
|
||||||
int realWidth = info.width << info.doubleSize;
|
int realWidth = info.width << info.doubleSize;
|
||||||
int realHeight = info.height << info.doubleSize;
|
int realHeight = info.height << info.doubleSize;
|
||||||
double cx = (realWidth - 1) * 0.5; // rotation center X in OBJ
|
double cx = (realWidth - 1) * 0.5; // rotation center X in OBJ
|
||||||
double cy = (realHeight - 1) * 0.5; // rotation center Y in OBJ
|
double cy = (realHeight - 1) * 0.5; // rotation center Y in OBJ
|
||||||
|
|
||||||
//transform coordinate origin by matrix transform
|
|
||||||
int movedX = x + realWidth / 2;
|
|
||||||
int movedY = y + realHeight / 2;
|
|
||||||
int movedX2 = FloatToInt(movedX * a + movedY * b);
|
|
||||||
int movedY2 = FloatToInt(movedX * c + movedY * d);
|
|
||||||
|
|
||||||
//un-correct moved position from center to top-left
|
|
||||||
movedX = movedX2 - realWidth / 2;
|
|
||||||
movedY = movedY2 - realHeight / 2;
|
|
||||||
|
|
||||||
for (int j = 0; j < realHeight; j++) {
|
for (int j = 0; j < realHeight; j++) {
|
||||||
int destY = (movedY + j + yOffs) & 0xFF;
|
int destY = (y + j + yOffs) & 0xFF;
|
||||||
for (int k = 0; k < realWidth; k++) {
|
for (int k = 0; k < realWidth; k++) {
|
||||||
int destX = (movedX + k + xOffs) & 0x1FF;
|
int destX = (x + k + xOffs) & 0x1FF;
|
||||||
|
|
||||||
int srcX = FloatToInt(((((double) k) - cx) * invA + (((double) j) - cy) * invB) + cx);
|
int srcX = FloatToInt(((((double) k) - cx) * invA + (((double) j) - cy) * invB) + cx);
|
||||||
int srcY = FloatToInt(((((double) k) - cx) * invC + (((double) j) - cy) * invD) + cy);
|
int srcY = FloatToInt(((((double) k) - cx) * invC + (((double) j) - cy) * invD) + cy);
|
||||||
|
Loading…
Reference in New Issue
Block a user