Matrix3D.deltaTransformVector in Flash & Html5


#1

Hi! I had a problem when working with Away3d.
After loading some models (say, 3DS) with transformation matrices and displaying them on the screen, the lighting did not work correctly (there was no diffuse light), because wrong calculated vertices normals (and tangents). Moreover, the problem is relevant when HTML5 is used; under the Flash everything worked correctly. After a few hours of searching, I found that when transforming the geometry, normals (and tangents) of vertices are transformed using the Matrix3D.deltaTransformVector, but this function is not performed equally in the flash and in the openfl, so all the normals are shifted somewhere during the transformation.
So, i think in Matrix3D.deltaTransformVector instead of

return new Vector3D ((x * rawData [0] + y * rawData [4] + z * rawData [8] + rawData [3]), (x * rawData [1] + y * rawData [5] + z * rawData [9] + rawData [7]), (x * rawData [2] + y * rawData [6] + z * rawData [10] + rawData [11], 0);

in openfl, there is another calculations in Flash:

Return new Vector3D ((x * rawData [0] + y * rawData [4] + z * rawData [8]), (x * rawData [1] + y * rawData [5] + z * rawData [9]), (x * rawData [2] + y * rawData [6] + z * rawData [10]), (x * rawData [3] + y * rawData [7] + z * rawData [11]));

Now everything works correctly after fixing this function for openfl, it’s just an information, i think it must be fixed in openfl :slight_smile:
Sorry for my english!


#2

Thanks!

Does this fix it for you?

It’s similar to your change, but the w property is set to zero.

The documentation suggests the translation should be ignored (like your fix) and w should be zero (like this fix) :slight_smile:


#3

Thanks, yes, it work’s fine now. I think w=0 will be ok for all cases, but just need to say, that internal Flash deltaTransformVector function returns

w=x * rawData[3] + y * rawData[7] + z * rawData[11]

as i can see from my tests with this function. Anyway, “w” result of this function is never used in away3d and i don’t think it will be used anywhere else :slight_smile:


#4

Huh, strange! The documentation says:

Note: This method automatically sets the w component of the passed Vector3D to 0.0.

Do you have any code handy that we could add to our unit tests, to confirm the behavior of the method? Don’t worry about having actual asserts, but just some quick mat = new Matrix3D (), mat.deltaTransformVector and the expected values of the returned vec instance?

Thank you :slight_smile:


#5

I don’t have Haxe right now :frowning: I have Flash CS6, so in order not to wait for the morning, i can test it, but in pure AS3 (in haxe result was the same, of course):

import flash.geom.Vector3D;
import flash.geom.Matrix3D;

var v:Vector.<Number> = new Vector.<Number>();
for (var i:int = 0; i < 16; i++)
v.push(i+1);

var a:Vector3D = new Vector3D(1,2,3,4);
var b:Matrix3D = new Matrix3D(v);
var c:Vector3D = b.deltaTransformVector(a);

trace(c.x,c.y,c.z,c.w);

result is

38 44 50 56


#6

Thanks! I’ve added both your original code, plus your code sample as a unit test.

I realize now, the documentation must mean that the w of the incoming vector is ignored. I guess. Either way, same behavior in Flash Player and in HTML5 now, and that’s what counts for this :success:


#7

Yes, that’s it, it works the same as transformVector, but with forcing w=0 in incoming vector.