Distortion Map pulling values from an array problem.

For questions about using Classic.

Post » Sun May 22, 2011 2:09 pm

I have a sprite with a 1x1 distortion map. The vertex positions are thus (0,0) (0,1) (1,0) (1,1). Four points in total. I also have a 2x2x3 array which stores precalcualted distortion values. X is Column, Y is Row, Z is distortion in X,Y and Z. Since I have 4 points, I have a looping event (looping 4 times) which updates each vertex with the proper distortion values. The problem is, no matter what I do, the last row never acquires the displacement values at all. They are in the array.

For"" from 0 to (Sprite.MeshRows+1)*(Sprite.MeshCols+1)-1
->
Set Absolute Displacement at
Row: floor(LoopIndex/2)
Col: (ceil(LoopIndex/2)-(LoopIndex/2))*2
X Distortion: Array((floor(LoopIndex/2)+1),((ceil(LoopIndex/2)-(LoopIndex/2))*2+1),1)
Y Distortion: Array((floor(LoopIndex/2)+1),((ceil(LoopIndex/2)-(LoopIndex/2))*2+1),2)
Z Distortion: Array((floor(LoopIndex/2)+1),((ceil(LoopIndex/2)-(LoopIndex/2))*2+1),3)

The formulae seem correct to me. The only way I found to mitigate the problem, was to add another row to the distortion map - basically adding empty space to the sprite and doubling its height -then my second row would acquire the distortion values while the third one would not.

Any help would be most apprectiated. Thanks.
B
8
S
2
G
2
Posts: 85
Reputation: 1,218

Post » Sun May 22, 2011 3:11 pm

it's difficult for me to decipher all that, but I'll give you some general info, arrays in construct are 1 based instead of 0 based, so the first index is 1, not 0.

also, your formula there is needlessly convoluted and unreadable, the (Sprite.MeshRows+1)*(Sprite.MeshCols+1)-1 make sure to use enough () to be sure about the order of operations even if it's superfluous just for readability. instead of using one loop with weird formulas to get what you need, why not just have nested loops?
for "x" from 0 to meshrows
for "y" from 0 to meshcols


then use loopindex("x"), and loopindex("y)
also, another thing that would make it less confusing would be not using a 3rd dimension to the array, and instead use 3 separate arrays named x, y, and z

other than that, using those alterations, it'll be quicker for you to find the solution than for me to. also, just for general info purposes, if you're sacrificing readability for optimization purposes, construct can have hundreds of objects all being acted upon and thousands of evaluated conditions and actions per frame with no slowdown, so you don't really need to do stuff like that except in extreme cases that most users never reach
Spriter Dev
B
87
S
21
G
12
Posts: 3,240
Reputation: 16,461

Post » Sun May 22, 2011 3:31 pm

I'm aware that Construct array are 1-indexed, that's why all of the distortion array coordinates have a +1, like so:

X Distortion: Array((floor(LoopIndex/2)+1),((ceil(LoopIndex/2)-(LoopIndex/2))*2+1),1)

I'll try the nested loops approach, though. Thanks for the help.
B
8
S
2
G
2
Posts: 85
Reputation: 1,218

Post » Sun May 22, 2011 3:43 pm

You can also set your loop to start at 1, and subtract 1 from loopindex when setting the map.
Image Image
B
161
S
48
G
90
Posts: 7,347
Reputation: 66,749

Post » Sun May 22, 2011 4:29 pm

Ok. Found the issue. It has to do with the ceil function.

If
ceil(0)=0
and
0/2=0
then
ceil(0/2)=0
right?

Well, for Construct, ceil(0/2) is actually 1.
And that's causing the Distortion Map to actually pull values out of the array's range...
B
8
S
2
G
2
Posts: 85
Reputation: 1,218

Post » Sun May 22, 2011 4:34 pm

wow...that's very strange. good find. please post a bug report
Spriter Dev
B
87
S
21
G
12
Posts: 3,240
Reputation: 16,461

Post » Sun May 22, 2011 4:54 pm

Posted. Bug 3305933 for those interested.
B
8
S
2
G
2
Posts: 85
Reputation: 1,218

Post » Sun May 22, 2011 6:40 pm

Um, that's not a bug, it's by design. There are 4 expressions to convert a floating point number to an integer: ceil, floor, round and int.

Ceil rounds the number up to the nearest integer.
ceil(0.1) =1
ceil(0.5) =1
ceil(4.9) =5

Floor rounds the number down to the nearest integer.
floor(0.1) =0
floor(0.5) =0
floor(4.9) =4

Round rounds the number down if the decimal part is less than .5 and up if it's greater than or equal to .5. It's just your basic arithmetic rounding.
round(0.1) =0
round(0.5) =1
round(4.9) =5

Int acts just like floor, it basically just discards the decimal part.
int(0.1) =0
int(0.5) =0
int(4.9) =4
B
79
S
24
G
52
Posts: 4,725
Reputation: 39,713

Post » Sun May 22, 2011 7:09 pm

I'm aware of how the ceiling function works. It returns the smallest integer not larger than the input. In the example I posted, ceil(0/2) gives 1. 0 divided by 2 is 0, which is an integer, so ceil should return 0.

EDIT:
I see what you mean. Whenever a number formated as a non-integer is passed to ceil, it takes the next one, even if that was a whole number. Ceil (1.0) will give 2. I still consider that wrong behavior, since even written as 1.0, 1 is an integer.

Additionally, the floor function works as expected. floor(1.0) will give 1, not 0.

Thanks for the explanation.
B
8
S
2
G
2
Posts: 85
Reputation: 1,218

Post » Sun May 22, 2011 7:30 pm

[quote:3572h17w]It returns the smallest integer not larger than the input.[/quote:3572h17w]
But by that logic wouldn't ceil(1.9) return 1?
Image Image
B
161
S
48
G
90
Posts: 7,347
Reputation: 66,749

Next

Return to Help & Support using Construct Classic

Who is online

Users browsing this forum: No registered users and 3 guests