PDA

View Full Version : [Direct3D] Problem with billboards.



Luuk van Venrooij
24-07-2008, 02:36 PM
Hi all,

I`m having a bit of trouble with billboards in Direct3D. I create an inverse matrix from the current view matrix. Then I set the position and scale. When I only set the position it work perfectly but when I also fill the scale the bilboard doesnt rotate anymore.


m_D3DDevice.GetTransform(D3DTS_VIEW, @d3dViewMat );
D3DXMatrixInverse(&d3dViewInversMat,nil,@d3dViewMat);
d3dViewInversMat._41 := pos.x();
d3dViewInversMat._42 := pos.y();
d3dViewInversMat._43 := pos.z();
d3dTransposedMat._11 := scale.x();
d3dTransposedMat._22 := scale.y();
d3dTransposedMat._33 := scale.z();
m_D3DDevice.SetTransform(D3DTS_WORLD, @d3dViewInversMat );


Anyone any Idears?

Grz

Luuk

JSoftware
24-07-2008, 02:51 PM
d3dTransposedMat._14 := scale.x();
d3dTransposedMat._24 := scale.y();
d3dTransposedMat._34 := scale.z();

Luuk van Venrooij
24-07-2008, 03:29 PM
I thought those where for the rotation. Anyway changed them and now I have really weired long deformed trails that don`t rotate at all.

JSoftware
24-07-2008, 04:17 PM
wait, are you using d3dTransposedMat at all?

and shouldn't you be doing this instead in DirectX?
d3dViewInversMat._14 := pos.x();
d3dViewInversMat._24 := pos.y();
d3dViewInversMat._34 := pos.z();
and then
d3dViewInversMat._41 := scale.x();
d3dViewInversMat._42 := scale.y();
d3dViewInversMat._43 := scale.z();

User137
24-07-2008, 09:25 PM
Are you sure that is the way to do scaling? I know that first 3x3 is for rotation x,y,z in 3 directions and 4th is for position, no idea what lies there under the 3 rows though. Maybe scaling is about multiplying the rotation vectors? Or maybe directx has some easier command to do that...

chronozphere
24-07-2008, 10:42 PM
@JSoftware: Are you serious? :? I've been working with D3D matrices for some time and as far as i know it's as follows:

If you don't transpose any matrices, it would be like this:

Mat._41 = Translate_X;
Mat._42 = Translate_Y;
Mat._43 = Translate_Z;

The upper-left 3x3 matrix (from _11 to _33) is for both rotation and scaling, so:

Mat._11 = Scale_X;
Mat._22 = Scale_Y;
Mat._33 = Scale_Z;

You shouldn't touch the (_14,_24,_34,_44) vector because that is used to transform the W component for each vertex. These value's should be 0,0,0,1 like the identity matrix. W is for perspective correction and should be 1.0.

A dumb suggestion of mine is to multiply the existing scaling value's with a scaling factor. Like:


d3dTransposedMat._11 := d3dTransposedMat._11 * scale.x();
d3dTransposedMat._22 := d3dTransposedMat._22 * scale.y();
d3dTransposedMat._33 := d3dTransposedMat._33 * scale.z();


Or try multiplying with a scale matrix. This way you preserve the existing rotation, while effectivly scaling your billboard. :)

It might work, but i could be wrong. I'm not a math-monster. :razz:

User137
25-07-2008, 08:06 AM
The upper-left 3x3 matrix (from _11 to _33) is for both rotation and scaling, so:
Mat._11 = Scale_X;
Mat._22 = Scale_Y;
Mat._33 = Scale_Z;
Your code does not multiply the entire vectors, should it?

So that's almost like my second suggestion. Maybe something like this?

var i: integer;
...
for i:=0 to 2 do begin
mat[i,0]:=mat[i,0]*Scale_X;
mat[i,1]:=mat[i,1]*Scale_Y;
mat[i,2]:=mat[i,2]*Scale_Z;
// or test flip the other way: mat[0,i]:=mat[0,i]*Scale_X; etc...
end;
// Oh, looked up my matrix functions and this is the exact way to do it.
As far as i know, OpenGL and DirectX use matrices in inverse to each other so that can sometimes cause fuss too.

Luuk van Venrooij
26-07-2008, 07:43 AM
Fixed the problem, a multiplication with a newly created scale matrix did the trick :)