Giter VIP home page Giter VIP logo

Comments (13)

walbourn avatar walbourn commented on May 20, 2024

The first thing to do is check that your ModelMesh has a non-zero bounding volume. The modern SDKMESH exporter and CMO mesh pipeline in Visual Studio should be creating a valid sphere bound, but there are some older SDKMESH models that are missing valid bounds. Because the SDKMESH does not contain a bounding sphere, one is created at load time from the bounding box.

Note that the center will not necessarily be (0,0,0) in model coordinates because this is not the most efficient sphere bound. The algorithm in DirectXMath's BoundingSphere::CreateFromPoints for example is from Ritter, Jack, An Efficient Bounding Sphere, Graphics Gems, Academic Press, 1990, p. 301-303, code: p. 723-725.

The code you provide is doing some really strange stuff with the center of the bounding box. You create a translation based on the bounding sphere center, and then transform the bounding box by that translation. The result is meaningless.

All you really need to do is transform the BoundingSphere by the same transform as you use for rendering the model. If you want to do collision in world-space, that would just be the 'world' matrix, not the camera's view & projection matrices.

XMMATRIX modelWorld = ...;
BoundingSphere worldSphere;
m_bounding.Transform(worldSphere, modelWorld);

BTW, for debugging collision geometry, you should take a look at DebugDraw

m_batch = std::make_unique<PrimitiveBatch<VertexPositionColor>>(context);
m_effect = std::make_unique<BasicEffect>(device);
m_effect->SetVertexColorEnabled(true);
{
    void const* shaderByteCode;
    size_t byteCodeLength;

    m_effect->GetVertexShaderBytecode(&shaderByteCode, &byteCodeLength);

    DX::ThrowIfFailed(
        device->CreateInputLayout(
            VertexPositionColor::InputElements, VertexPositionColor::InputElementCount,
           shaderByteCode, byteCodeLength,
            m_layout.ReleaseAndGetAddressOf()));
}

...

XMMATRIX modelWorld = ...;
XMMATRIX view = m_Camera.ViewMatrix();
XMMATRIX proj = m_Camera.ProjectionMatrix();
m_Tree->Draw( context, *m_states, modelWorld, view, proj);

#ifdef _DEBUG
// Draws an outline of the bounding volume over the model
context->OMSetBlendState(m_states->Opaque(), nullptr, 0xFFFFFFFF);
context->OMSetDepthStencilState(m_states->DepthNone(), 0);
context->RSSetState(m_states->CullNone());
m_effect->Apply(context);
context->IASetInputLayout(m_layout.Get());
m_batch->Begin();
m_effect->SetView(view);
m_effect->SetProjection(proj);

BoundingSphere worldSphere;
m_bounding.Transform(worldSphere, modelWorld);

DX::Draw(m_batch.get(), worldSphere);
m_batch->End();
#endif

from directxtk.

walbourn avatar walbourn commented on May 20, 2024

It's in the link I gave you. DebugDraw.h and DebugDraw.cpp.

from directxtk.

AndreAhmed avatar AndreAhmed commented on May 20, 2024

I have the following code, but the sphere is translated and its not surrounding the tree. its translated behind it.

here is how I'm rendering it

XMMATRIX treeTranslate = XMMatrixTranslation(100, -100, 112);

    // Convert rotation into radians.
    float angle = atan2(100 - m_Camera.Position().x, 112 - m_Camera.Position().z) * (180.0 / XM_PI);
    float treeRot = (float)angle * 0.0174532925f;
    XMMATRIX treeRotation = XMMatrixRotationY(treeRot);
    XMMATRIX treeWorld = treeRotation*treeTranslate; // THIS IS THE IMPORTANT WORLD, THE ROTATION IS IMPORTANT TO INCLUDE

    m_Tree->Draw(m_Graphics.getContext(), states, treeWorld, m_Graphics.getViewMatrix(),
        m_Camera.ProjectionMatrix());

    m_bounding = m_Tree->meshes.at(0)->boundingSphere;

    m_batch->Begin();

    m_bounding.Transform(m_bounding, treeWorld);

    m_effect->SetView(m_Camera.ViewMatrix());
    m_effect->SetProjection(m_Camera.ProjectionMatrix());
    Draw(m_batch.get(), m_bounding, Colors::Red);
    m_batch->End();

here is the picture
untitled

from directxtk.

walbourn avatar walbourn commented on May 20, 2024

What's the original values in m_Tree->meshes.at(0)->boundingSphere?

from directxtk.

AndreAhmed avatar AndreAhmed commented on May 20, 2024

m_bounding {Center={x=0.00674819946 y=72.5237503 z=-0.932399750 } Radius=110.144882 } DirectX::BoundingSphere

from directxtk.

walbourn avatar walbourn commented on May 20, 2024

Ok. It looks valid at least.

That said, m_bounding.Transform(m_bounding, treeWorld); means you are modifying the bounding sphere every frame you render which is not what you want to do. Make a temporary:

BoundingSphere treeSphere;
m_bounding.Transform(treeSphere, treeWorld);

m_effect->SetView(m_Camera.ViewMatrix());
m_effect->SetProjection(m_Camera.ProjectionMatrix());
Draw(m_batch.get(), treeSphere, Colors::Red);
m_batch->End();

from directxtk.

AndreAhmed avatar AndreAhmed commented on May 20, 2024

still the sphere is in wrong place

from directxtk.

walbourn avatar walbourn commented on May 20, 2024

Sure, but we are getting closer.

Check the values of m_bounding, treeSphere, and treeWorld to make sure they make sense to you.

Also, what's the value of m_Tree->meshes.at(0)->boundingBox?

What format is your model loading from?

from directxtk.

AndreAhmed avatar AndreAhmed commented on May 20, 2024

I use the directx sdkmesh, converted from an obj file.
m_bounding = {Center={x=0.00674819946 y=72.5237503 z=-0.932399750 } Radius=110.144882 }
treeSphere = {Center={x=99.1690521 y=-27.4762497 z=111.576981 } Radius=110.144882 }

tree world

untitled

from directxtk.

AndreAhmed avatar AndreAhmed commented on May 20, 2024

Bounding box :

box = {Center={x=0.00674819946 y=72.5237503 z=-0.932399750 } Extents={x=58.6604500 y=73.0773544 z=57.8838997 } }

from directxtk.

AndreAhmed avatar AndreAhmed commented on May 20, 2024

here is how I do the picking, which is incorrect due to the bounding sphere calculation is wrong, do you find a problem with it ?


void GameApp::Pick(int sx, int sy, XMVECTOR & pickRayInWorldSpacePos, XMVECTOR &pickRayInWorldSpaceDir)
{
    XMVECTOR pickRayInViewSpaceDir = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
    XMVECTOR pickRayInViewSpacePos = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);

    float PRVecX, PRVecY, PRVecZ;
    XMFLOAT4X4 tmp;
    XMStoreFloat4x4(&tmp, m_Camera.ProjectionMatrix());
    //Transform 2D pick position on screen space to 3D ray in View space
    PRVecX = (((2.0f * sx) / 784) - 1) / tmp.m[0][0];
    PRVecY = -(((2.0f * sy) / 562) - 1) / tmp.m[1][1];
    PRVecZ = 1.0f;  //View space's Z direction ranges from 0 to 1, so we set 1 since the ray goes "into" the screen

    pickRayInViewSpaceDir = XMVectorSet(PRVecX, PRVecY, PRVecZ, 0.0f);

    //Uncomment this line if you want to use the center of the screen (client area)
    //to be the point that creates the picking ray (eg. first person shooter)
    //pickRayInViewSpaceDir = XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f);

    // Transform 3D Ray from View space to 3D ray in World space
    XMMATRIX pickRayToWorldSpaceMatrix;
    XMVECTOR matInvDeter;   //We don't use this, but the xna matrix inverse function requires the first parameter to not be null

    pickRayToWorldSpaceMatrix = XMMatrixInverse(&matInvDeter, m_Camera.ViewMatrix());   //Inverse of View Space matrix is World space matrix

    pickRayInWorldSpacePos = XMVector3TransformCoord(pickRayInViewSpacePos, pickRayToWorldSpaceMatrix);
    pickRayInWorldSpaceDir = XMVector3TransformNormal(pickRayInViewSpaceDir, pickRayToWorldSpaceMatrix);
    pickRayInWorldSpaceDir = XMVector3Normalize(pickRayInWorldSpaceDir);

    float dist;
    if (m_bounding.Intersects(pickRayInWorldSpacePos, pickRayInWorldSpaceDir, dist) == true)
    {
        m_Picked++;
    }

}

from directxtk.

AndreAhmed avatar AndreAhmed commented on May 20, 2024

its fixed, I was not applying the effect.
untitled

but I have another problem, as shown in the image the sphere is large and doesn't surround the tree, how would I scale it ?

from directxtk.

walbourn avatar walbourn commented on May 20, 2024

That makes more sense :)

The issue here is that the bounding sphere is not a particularly tight bound because of the way it is created. Try picking against the boundingBox instead (there's a DebugDraw for the box) and see if that's a better bound for your model.

from directxtk.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.