# Float to Pixel

This topic is 3454 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hey guys this is my first post! Recently I had the same problem as someone known as WinRad - How to convert a world space value to a screen space one, but by reading the replies figured that out. Suprisingly though I also had the size problem same as WinRad, which was answered by someone. Although I understood it my function still messed up and I'm hoping you pros could take a look ---> [code = C++] RECT ParticleSystem::GetParticleRect(D3DXVECTOR3 GPRPos, FLOAT GPRSize) { INT Left, Top, Right, Bottom; RECT ParticlePosition; D3DXMATRIX View, Projection, Identity; D3DVIEWPORT9 VP; D3DXVECTOR3 ParticlePos, TempSize1, ActualSize; GameInformation.D3DDevice->GetTransform(D3DTS_VIEW, &View); GameInformation.D3DDevice->GetTransform(D3DTS_PROJECTION, &Projection); GameInformation.D3DDevice->GetViewport(&VP); D3DXMatrixIdentity(&Identity); D3DXVec3Project(&ParticlePos, &GPRPos, &VP, &Projection, &View, &Identity); D3DXVec3Project(&TempSize1, &D3DXVECTOR3(GPRPos.x + GPRSize, GPRPos.y + GPRSize, 0.0f), &VP, &Projection, &View, &Identity); ActualSize.x = (TempSize1.x - ParticlePos.x); ActualSize.y = (TempSize1.y - ParticlePos.y); Left = ParticlePos.x - ActualSize.x; Top = ParticlePos.y - ActualSize.y; Right = ParticlePos.x + ActualSize.x; Bottom = ParticlePos.y + ActualSize.y; SetRect(&ParticlePosition, Left, Top, Right, Bottom); return ParticlePosition; } Basicly it should work out the borders of my particle yet it doesn't. What happens instead is the it works out the centre of my particle so left, top, right and bottom are equal to the centre. Thanks!!!

##### Share on other sites

Part of me thinks your approach is mathematically flawed as the shape is view dependent, and whilst that is desirable I wondered if you had to handle it in a different way...

You can fairly easily break down the D3DXVec3Project() operation into component matrix operations and step through it. I'd highly recommend you do some step-through debugging of known test data and identity matrices and go back to first principles. It should become clear which operation or which bit of data is not doing what you expect it to.

hth
Jack

##### Share on other sites
Hard to say from your code. I'd suggest running your program in debug, and verifying that GPRSize is non-zero.

##### Share on other sites
Thanks for the replies, currently I do get the correct results for the centre of the particle, but when it comes to the size it just ain't workin' for me... so I think the problem may be with the GPRSize variablr... I'll check it when I get home and tell you guys my report.

##### Share on other sites
Well I tested the variable and it seems that the variable is being passed the correct value... but there was a problem and it was that the value ended being negative so I just reversed it and it started working but yet there is another problem; the rectangle around the circle is too small for some reason so I multiplicated the value for it by two... but I think there is something wrong and I just don't get it. Here's the new code --->

RECT ParticleSystem::GetParticleRect(D3DXVECTOR3 GPRPos, FLOAT GPRSize){ INT Left, Top, Right, Bottom; RECT ParticlePosition; D3DXMATRIX View, Projection, Identity; D3DVIEWPORT9 VP; D3DXVECTOR3 ParticlePos, TempSize1, ActualSize; GameInformation.D3DDevice->GetTransform(D3DTS_VIEW, &View); GameInformation.D3DDevice->GetTransform(D3DTS_PROJECTION, &Projection); GameInformation.D3DDevice->GetViewport(&VP);  D3DXMatrixIdentity(&Identity); D3DXVec3Project(&ParticlePos, &GPRPos, &VP, &Projection, &View, &Identity); D3DXVec3Project(&TempSize1, &D3DXVECTOR3(GPRPos.x + GPRSize, GPRPos.y + GPRSize, 0.0f), &VP, &Projection, &View, &Identity); ActualSize.x = -(TempSize1.x - ParticlePos.x); //Reversed ActualSize.y = -(TempSize1.y - ParticlePos.y); //Reversed Left = ParticlePos.x - ActualSize.x * 2;   //Temporarily the Top = ParticlePos.y - ActualSize.y * 2;    //values have been multiplicated Right = ParticlePos.x + ActualSize.x * 2;  //as the rectangle is just too  Bottom = ParticlePos.y + ActualSize.y * 2; //small... SetRect(&ParticlePosition, Left, Top, Right, Bottom); return ParticlePosition;}

Any ideas on what went wrong?

Thanks.

[Edited by - SlickKobra on August 22, 2008 9:57:19 PM]

##### Share on other sites
LEFT, TOP, RIGHT, and BOTTOM are integers. If the particle size is very small (less than a pixel), it'll be rounded down to zero. Try making float versions of those and checking them out in a debugger.

##### Share on other sites
You mind me tellin' you that I love you? Hehe joking :).

It seems so obvious now! I'll go home and use D3DXVECTOR4(from memory) for the rectangle instead of a RECT struct. It will probably work though.

##### Share on other sites
Unblievable! For some reason I'm basically getting the same results! Well here's the updated code and yet I still don't know what's wrong :( -

D3DXVECTOR4 ParticleSystem::GetParticleRect(D3DXVECTOR3 GPRPos, FLOAT GPRSize){ D3DVIEWPORT9 VP; D3DXMATRIX View, Projection, Identity; D3DXVECTOR3 ParticlePos, TempSize1, ActualSize; D3DXVECTOR4 ParticleRectangle; FLOAT Left, Top, Right, Bottom; GameInformation.D3DDevice->GetTransform(D3DTS_VIEW, &View); GameInformation.D3DDevice->GetTransform(D3DTS_PROJECTION, &Projection); GameInformation.D3DDevice->GetViewport(&VP);  D3DXMatrixIdentity(&Identity); D3DXVec3Project(&ParticlePos, &GPRPos, &VP, &Projection, &View, &Identity); D3DXVec3Project(&TempSize1, &D3DXVECTOR3(GPRPos.x + GPRSize, GPRPos.y + GPRSize, 0.0f), &VP, &Projection, &View, &Identity); ActualSize.x = -(TempSize1.x - ParticlePos.x); ActualSize.y = -(TempSize1.y - ParticlePos.y); Left = ParticlePos.x - ActualSize.x; Top = ParticlePos.y - ActualSize.y; Right = ParticlePos.x + ActualSize.x; Bottom = ParticlePos.y + ActualSize.y; ParticleRectangle.w = Left; ParticleRectangle.x = Top; ParticleRectangle.y = Right; ParticleRectangle.z = Bottom; return ParticleRectangle;}

If you even have the slightest of clues on what may be wrong then please say so.

Thanks :(.

##### Share on other sites
Guys isn't there anything wrong with the code? I mean its throwing me false values everywhere... Can someone please just tell me what is wrong with the code? Or please make a function of your own that takes a central position of a particle and size and then returns a D3DXVECTOR4 variable which is the boundary of the particle.

The central position(where the particle is) variable = D3DXVECTOR3 Pos.
The size of the particle = FLOAT Size;

Thanks you!

##### Share on other sites
Quote:
 Original post by SlickKobra D3DXVec3Project(&ParticlePos, &GPRPos, &VP, &Projection, &View, &Identity); D3DXVec3Project(&TempSize1, &D3DXVECTOR3(GPRPos.x + GPRSize, GPRPos.y + GPRSize, 0.0f), &VP, &Projection, &View, &Identity); ActualSize.x = -(TempSize1.x - ParticlePos.x); ActualSize.y = -(TempSize1.y - ParticlePos.y);

Are you sure this is correct?
Do the particles simply get the wrong size but correct relative-to-distance size scale, or is the distance-to-size scale wrong?
Try ActualSize = Constant * GPRSize / Z-Distance-to-particle and see what happens.

##### Share on other sites
Thanks for the post :D.

I don't really understand what you said but i'm guessing it has to do with the z axis... well, i'm not really using the z axis; rather just x and y. If my particle was 2cm by 2cm big(in real life) then the rectangle which should also be the same is instead something like 1.5cm by 1.5cm big. What I just said in my last sentence is infact the problem... the rectangle is smaller then the actual circle.

Thanks man!

##### Share on other sites
I think you should try something like this, not entirely sure though:
Project the particle position as you do, and save that projected position.
Then for the size part, multiply your world position with the View matrix only, so that you get the viewspace position. That is the position relative to your camera.
Then add the particle's size X/Y to that viewspace position, and then project that result. Now you will have a projected version of a worldspace size, which I think is what you want.

So it would be something like:
ParticlePos = D3DXVec3Project(GPRPos, ....);ViewPos = GPRPos * View;ViewPos.x += GPRSize;ViewPos.y += GPRSize;TempSize1 = ViewPos * Projection;x = TempSize1.x - ParticlePos.x;y = TempSize1.y - ParticlePos.y;

##### Share on other sites
Sorry for my idiosity :( I just don't get it. Could you please edit my function so that it will do... what I want it to?

Thanks.

##### Share on other sites
I'm not sure, I have no D3D9 project to test it with and see if it gives the correct results, which I'm still a bit unsure what they are =)
But try this:
GPRSize is the size the particle should have in worldspace.

D3DXVECTOR4 ParticleSystem::GetParticleRect(D3DXVECTOR3 GPRPos, FLOAT GPRSize){ D3DVIEWPORT9 VP; D3DXMATRIX View, Projection, Identity; D3DXVECTOR3 ParticlePos, TempSize1, ActualSize; D3DXVECTOR4 ParticleRectangle; FLOAT Left, Top, Right, Bottom; GameInformation.D3DDevice->GetTransform(D3DTS_VIEW, &View); GameInformation.D3DDevice->GetTransform(D3DTS_PROJECTION, &Projection); GameInformation.D3DDevice->GetViewport(&VP);  D3DXMatrixIdentity(&Identity); D3DXVec3Project(&ParticlePos, &GPRPos, &VP, &Projection, &View, &Identity);  // Replace the second Project with this... D3DXVECTOR4	TempSize4, TempSize42; D3DXVec3Transform(&TempSize4, &GPRPos, &View); TempSize4.x += GPRSize; TempSize4.y += GPRSize; D3DXVec4Transform(&TempSize42, &TempSize4, &Projection); TempSize1 = D3DXVECTOR3(TempSize42); // ActualSize.x = -(TempSize1.x - ParticlePos.x); ActualSize.y = -(TempSize1.y - ParticlePos.y); Left = ParticlePos.x - ActualSize.x; Top = ParticlePos.y - ActualSize.y; Right = ParticlePos.x + ActualSize.x; Bottom = ParticlePos.y + ActualSize.y; ParticleRectangle.w = Left; ParticleRectangle.x = Top; ParticleRectangle.y = Right; ParticleRectangle.z = Bottom; return ParticleRectangle;}

##### Share on other sites
Thanks for trying man! But sadly no dice :(. The particles go straight up(while wiggling).

But damn it! What's so wrong with my code that I showed everyone? The mathamatics seem correct. I mean... ugh. I just don't know what to do... are there any documents/tutorials online that teach you how to get a border of an object in world space?

Thanks for the effort to help!

##### Share on other sites
Try allocating space for your ActualSize vector. I'm not familiar with d3d but I don't see anything in your code to either get it from somewhere else or malloc or new. I'm surprised you're not seg faulting.

You probably want to call the constructor somehow for the D3DXVECTOR3 and store its return in ActualSize.

Edit:

ActualSize = new D3DXVECTOR3();

needs to come before

ActualSize.x = -(TempSize1.x - ParticlePos.x);
ActualSize.y = -(TempSize1.y - ParticlePos.y);

##### Share on other sites

D3DXVECTOR3 is not a stl like container. it is just 3 DOUBLES pact together.

There is no memory isue, sure he could have initialized it in some why before using it, but that's only nitpicking, not the real problem.