Sign in to follow this  
SlickKobra

Float to Pixel

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; } [/code] 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 this post


Link to post
Share on other sites
I was thinking about this post yesterday but couldn't come to a conclusion worth posting.

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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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.

Unless I reply again - This thread is resolved.

Share this post


Link to post
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 this post


Link to post
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 this post


Link to post
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);
[/code]


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 this post


Link to post
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.

Please help me out because my program's status is at a stand-still :(!

Thanks man!

Share this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this