convert 3D point to 2D - for botloot

09/02/2009 10:11 Ikaruz#1
Hi there,

a few days ago I was testing different lootroutines for botting. None of them worked perfect and I'm not *satisfied* with the result. I checked the cursortype and/or the mouseover-objectpointer. The problem is that the games need some time to *realize* that the mousecursorposition changed, so the cursortype and the mouseover-objectpointer change *to slow*. To avoid this problem I could just wait a few milliseconds and it would work. But this slows down the looting extremly and I dont like that. Another problem with this method is: it depends on the speed of a computer. If the value of the 'wait-delay' on a slow computer is to small the looting wouldn't work. So I thought I need something better here.

Then I had the idea to convert the 3D (resource-/deadmob-)coordinates into a 2D point on the screen. If that would work I could always place the cursor at the perfect x-y-screenposition for looting (instead of 'scanning' the screen and wait until the cursor changes or other shit). Since I have never done anything like this before I *googled* and found out how to do this:

2D Point = 3D Point * WorldViewProjectionMatrix
WorldViewProjectionMatrix = World Matrix * View Matrix * Projection Matrix

To understand this I found this awesome(!) link:
[Only registered and activated users can see links. Click Here To Register...]

So to do this I need the object-3D Point, the World Matrix, View Matrix and Projection Matrix. The only thing I have is the 3D Point of the object (the origin, note: a vertex should be better but it sould work fine with the origin-point because in RoM they seem to be in the middle of the object).

But how can I find out where the game stores the matrices? All I know its a block/array of 4x4 floats.

(sidenote: this stuff is not only for looting, its possible to create 2D Radars like the one in the botsmall-bot)
09/03/2009 19:31 ~Crystal Magician~#2
Interesting idea. The 2D Radar would be useful. I've used one for Warhammer Online before and they really are useful.
09/05/2009 16:52 Ikaruz#3
[Only registered and activated users can see links. Click Here To Register...]
wahhhhhhhhhhh :facepalm: this stuff makes me crazy!!!
PHP Code:
    D3DXVECTOR3 *vScreenCoord;
    
D3DXMATRIX projectionviewworld;
    
D3DVIEWPORT9 viewPort;
    
D3DXVECTOR3 vWorldLocation(collectlist[0].object.xcollectlist[0].object.ycollectlist[0].object.z);

    
pD3Ddevice->GetTransform(D3DTS_VIEW, &view);
    
pD3Ddevice->GetTransform(D3DTS_PROJECTION, &projection);
    
pD3Ddevice->GetTransform(D3DTS_WORLD, &world);
    
pD3Ddevice->GetViewport(&viewPort);

    
D3DXVec3Project(vScreenCoord, &vWorldLocation, &viewPort, &projection, &view, &world);

    
SetCursorposition(int(vScreenCoord->x),int(vScreenCoord->y));
    
Mouseclick(); 
I'm so damn close to get this working and now there is new problem. Look at this exactly, see the flags that Runes of Magic uses to create the Direct3D-Device?!
[Only registered and activated users can see links. Click Here To Register...]
Why is this bad? Because of the damn "D3DCREATE_PUREDEVICE"-flag I cant use pD3Ddevice->GetTransform(/*stuff*/). :mad:

I have the devicepointer and everything works fine except GetTransform()! *grml*

quote from MSDN about the flag:
Quote:
What is the purpose of the D3DCREATE_PUREDEVICE flag?

Use the D3DCREATE_PUREDEVICE flag during device creation to create a pure device. A pure device does not save the current state (during state changes), which often improves performance; this device also requires hardware vertex processing. A pure device is typically used when development and debugging are completed, and you want to achieve the best performance.

One drawback of a pure device is that it does not support all Get* API calls; this means you can not use a pure device to query the pipeline state. This makes it more difficult to debug while running an application. Below is a list of all the methods that are disabled by a pure device.

* ID3D10Device9::GetClipPlane
* ID3D10Device9::GetClipStatus
* ID3D10Device9::GetLight
* ID3D10Device9::GetLightEnable
* ID3D10Device9::GetMaterial
* ID3D10Device9::GetPixelShaderConstantF
* ID3D10Device9::GetPixelShaderConstantI
* ID3D10Device9::GetPixelShaderConstantB
* ID3D10Device9::GetRenderState
* ID3D10Device9::GetSamplerState
* ID3D10Device9::GetTextureStageState
* ID3D10Device9::GetTransform
* ID3D10Device9::GetVertexShaderConstantF
* ID3D10Device9::GetVertexShaderConstantI
* ID3D10Device9::GetVertexShaderConstantB

A second drawback of a pure device is that it does not filter any redundant state changes. When using a pure device, your application should reduce the number of state changes in the render loop to a minimum; this may include filtering state changes to make sure that states do not get set more than once. This trade-off is application dependent; if you use more than a 1000 Set calls per frame, you should consider taking advantage of the redundancy filtering that is done automatically by a non-pure device.

As with all performance issues, the only way to know whether or not your application will perform better with a pure device is to compare your application's performance with a pure vs. non-pure device. A pure device has the potential to speed up an application by reducing the CPU overhead of the API. But be careful! For some scenarios, a pure device will slow down your application (due to the additional CPU work caused by redundant state changes). If you are not sure which type of device will work best for your application, and you do not filter redundant changes in the application, use a non-pure device.
damn Runewalker, I HATE THEM!
09/05/2009 17:14 ntKid#4
Game is most likely not using settransform to set the matrices. ( you can make sure by hooking settransform and returning a D3D_OK if the char doesnt f*ck up then its shader driven ).
From what u said so far it sounds like a shader driven game [Only registered and activated users can see links. Click Here To Register...] , cheers
09/05/2009 19:22 Ikaruz#5
I think you are right. I patched the client.exe so that CreateDevice()-function will no longer use the *puredevice*-flag. Then I tested again and this time the GetTranslation()-function worked (returned OK). BUT the World-, View- and Projectionmatrices only contained the float values 0.0f oder 1.0f.

Now I have even more problems:
-at first I MUST find a way to disable the *puredevice*-flag at runtime! No matter what method I use, to get the matrices I have to call either GetTransform() or GetVertexShaderConstantF()! Both functions won't work if the d3ddevice was create with the *puredevice*-flag. Actually I'm not sure whether it's possible to disable the flag after the d3ddevice was created, this could be a big problem.

-I have never ever written any d3d-appl. in my life (only OpenGL some years ago) and looking at your code confused me and I'm not sure whether all this is worth the efford, this turned out to be much more complex the I ever thought ... I mean all I want is to place a cursor on a 3D-object
09/07/2009 12:09 Ikaruz#6
/talking to myself

I placed a breakpoint on SetTransform() and Runes of Magic breaked there but only during the startup. While being ingame in never breakes there. Looks like I'll have to deal with the shaders to get the matrices.

Then I made a little test-DLL that uses your (ntKid's) code. Thats the result:
PHP Code:
Name=[g_globalParams]
RegisterSet=[D3DXRS_FLOAT4]
RegisterIndex=[0]
RegisterCount=[1]
Class=[
D3DXPC_VECTOR]
Type=[D3DXPT_FLOAT]
Rows=[1]
Columns=[4]
Elemets=[1]
StructMembers=[0]
Bytes=[16]
DefaultValue=[0x0]
StartRegister=[0]
END

Name
=[g_instanceData]
RegisterSet=[D3DXRS_FLOAT4]
RegisterIndex=[2]
RegisterCount=[252]
Class=[
D3DXPC_VECTOR]
Type=[D3DXPT_FLOAT]
Rows=[1]
Columns=[4]
Elemets=[252]
StructMembers=[0]
Bytes=[4032]
DefaultValue=[0x0]
StartRegister=[1]
END 
This doesn't look lika matrix stuff ... now I'm completly lost ...
09/08/2009 15:50 ntKid#7
Just wondering if u have the object coords, player coords and camera viewangles by memory u could have a go at OGC worldtoscreen and not use d3d at all will save u time with model rec, either way will have a flaw, collision detection case the object is behind a tree its gonna click the tree instead =(, anyhow good luck =)