Code Monkey home page Code Monkey logo

Comments (17)

jrouwe avatar jrouwe commented on May 11, 2024

I'm not sure if I understand correctly. Drawing a ShapeCast or RayCast would be easy (it's only a couple of lines of code, see e.g. SamplesApp::CastProbe), but since there are various ways you can use that Ray/ShapeCast that work in different spaces it may be just as confusing. E.g. Shape::RayCast works against the shape centered around its COM, TransformedShape::CastRay / NarrowPhaseQuery::CastRay takes a world space RayCast.

from joltphysics.

Joshua-Ashton avatar Joshua-Ashton commented on May 11, 2024

I guess this stems from what we are trying to debug with our current integration.

Right now, when we take our ShapeCast and set the inCenterOfMassStart to that of the worldspace box center and inDirection to it's direction, and then set inCenterOfMassTransform2 to the worldspace transform of the object, we get no hits except at the origin of the map. Whereas if we instead take the ShapeCast and PostTransform it with the inverse of the transform of the object and set the inCenterOfMassTransform2 to Identity, things hit fine, and we were wanting to visualize why this is happening cause it doesn't seem to make much sense to me at least.

A secondary thing we are trying to debug is whether the output normal after rotating it is correct, and also the two objects.
Right now there's an issue where we are getting hits that we are reporting as starting inside, whereas on the game side they should not be a hit, it should just be 'touching' ie. frac = 0 but no penetration. And we were wanting to see visually what was happening here to try and resolve it (eg. take the dot product of the normal post-rotation and the ray dir to modify the real hit length with some epsilon * dot and stuff to see if we can make this behave like we had in the old physics system or whatever.)

Sorry for the kind of vague wall of text here.

We have some stuff to visualize right now, but we were wanting to make sure that we weren't completely off-base looking at the wrong thing so I was thinking maybe it would be better if Jolt had some helpers to debug here so we can see exactly what Jolt is seeing wrt the two objects on its end.

from joltphysics.

jrouwe avatar jrouwe commented on May 11, 2024

My guess is that the object that you're colliding against has a Shape::GetCenterOfMass() of non-zero. If you pass in the world transform of that object, you're not passing in the center of mass transform (which is what inCenterOfMassTransform2 expects). You should be passing inCenterOfMassTransform2 = WorldTransform * Mat44::sTranslation(target_shape->GetCenterOfMass()).

from joltphysics.

Joshua-Ashton avatar Joshua-Ashton commented on May 11, 2024

We are doing that. Commented out is the path that works, uncommented is using inCenterOfMassTransform2 that doesn't work.

These two should have the same behaviour, unless I am missing something...

JPH::Mat44 queryTransform = JPH::Mat44::sRotationTranslation( rotation, position + rotation * pShape->GetCenterOfMass() );

JPH::BoxShape boxShape( SourceToJolt( ray.m_Extents ) );
JPH::ShapeCast initialShapeCast( &boxShape, JPH::Vec3::sReplicate( 1.0f ), JPH::Mat44::sTranslation( origin ), direction );
// What works is commented.
//JPH::ShapeCast shapeCast = initialShapeCast.PostTransformed( queryTransform.InversedRotationTranslation() );
JPH::ShapeCast shapeCast = initialShapeCast;

JPH::ShapeCastSettings settings;
settings.mBackFaceModeTriangles = JPH::EBackFaceMode::CollideWithBackFaces;
settings.mBackFaceModeConvex = JPH::EBackFaceMode::CollideWithBackFaces;

ContentsShapeFilter filter( pShape, contentsMask, pConvexInfo );
ContentsShapeCollector collector( pShape, contentsMask, pConvexInfo );
// What works is commented.
//JPH::CollisionDispatch::sCastShapeVsShape( shapeCast, settings, pShape, JPH::Vec3::sReplicate( 1.0f ), filter, JPH::Mat44::sIdentity(), JPH::SubShapeIDCreator(), JPH::SubShapeIDCreator(), collector );
JPH::CollisionDispatch::sCastShapeVsShape( shapeCast, settings, pShape, JPH::Vec3::sReplicate( 1.0f ), filter, queryTransform, JPH::SubShapeIDCreator(), JPH::SubShapeIDCreator(), collector );

(also worth noting that doing JPH::Mat44::sRotationTranslation( ... ) * JPH::Mat44::sTranslation( blah->GetCenterOfMass() ) has no effect either, but these two should be identical anyway)

from joltphysics.

jrouwe avatar jrouwe commented on May 11, 2024

Hmmm, it looks like your code is correct (or at least the commented and uncommented parts are equivalent as far as I can see). I would need to debug this. Can you provide some code to initialize origin, direction, position, rotation, ray.m_Extents and pShape for a case where the commented code works and the uncommented code doesn't? (I can insert my own filter and collector)

from joltphysics.

Joshua-Ashton avatar Joshua-Ashton commented on May 11, 2024

Sure, hopefully I can get away with serializing my convex shape and unserializing for the test

from joltphysics.

Joshua-Ashton avatar Joshua-Ashton commented on May 11, 2024

Hi, I attempted to make that test today, but unfortunately serializing the shape doesn't work correctly, it is a StaticCompoundShape and all of the subshapes become NULL when restoring from the binary

from joltphysics.

Joshua-Ashton avatar Joshua-Ashton commented on May 11, 2024

Ah, I think I need to use SaveWithChildren and such...

from joltphysics.

Joshua-Ashton avatar Joshua-Ashton commented on May 11, 2024

Welp, that doesn't work, just fails with "Failed to restore shape."

Here is the .bin for the shape to use with sRestoreWithChildren that fails and was dumped straight from the engine with SaveWithChildren straight to a file.

my_collide_new.bin.removethetxt.txt

from joltphysics.

jrouwe avatar jrouwe commented on May 11, 2024

Do you also have all other parameters (position etc.)? I.e can you write a code snippet that works with the commented out code but doesn't with the other code?

from joltphysics.

Joshua-Ashton avatar Joshua-Ashton commented on May 11, 2024

Sure:

		std::ifstream myfile("C:\\Users\\Joshua\\my_collide.bin");
		JPH::StreamInWrapper wrapper(myfile);
		JPH::Shape::IDToShapeMap id_to_shape;
		JPH::Shape::IDToMaterialMap id_to_material;
		auto shapey = JPH::Shape::sRestoreWithChildren(wrapper, id_to_shape, id_to_material).Get();

		JPH::Shape* pShape = shapey.GetPtr();

		JPH::Vec3 collidePosition = Vec3(0x1.00d8440000000p+5, 0x1.1e1b080000000p+2, 0x0.0000000000000p+0);
		JPH::Quat collideRotation = Quat(0x0.0000000000000p+0, 0x0.0000000000000p+0, 0x0.0000000000000p+0, 0x1.fffffc0000000p-1);

		JPH::Mat44 queryTransform = JPH::Mat44::sRotationTranslation(collideRotation, collidePosition + collideRotation * pShape->GetCenterOfMass());

		JPH::Vec3 boxPosition = JPH::Vec3(0x1.f84b940000000p+4, 0x1.81e37e0000000p+1, 0x1.dab9d20000000p+2);
		JPH::Vec3 boxDirection = JPH::Vec3(0x0.0000000000000p+0, 0x0.0000000000000p+0, -0x1.0418940000000p-1);
		JPH::Vec3 boxHalfExtent = JPH::Vec3(0x1.a027520000000p-2, 0x1.a027520000000p-2, 0x1.d42c3c0000000p-1);

		JPH::BoxShape boxShape(boxHalfExtent);

		JPH::ShapeCast initialShapeCast(&boxShape, JPH::Vec3::sReplicate(1.0f), JPH::Mat44::sTranslation(boxPosition), boxDirection);
		//JPH::ShapeCast shapeCast = initialShapeCast.PostTransformed(queryTransform.InversedRotationTranslation());
		JPH::ShapeCast shapeCast = initialShapeCast;

		JPH::ShapeCastSettings settings;
		JPH::ShapeFilter filter;
		JPH::AnyHitCollisionCollector<JPH::CastShapeCollector> collector;
		//JPH::CollisionDispatch::sCastShapeVsShape(shapeCast, settings, pShape, JPH::Vec3::sReplicate(1.0f), filter, JPH::Mat44::sIdentity(), JPH::SubShapeIDCreator(), JPH::SubShapeIDCreator(), collector);
		JPH::CollisionDispatch::sCastShapeVsShape(shapeCast, settings, pShape, JPH::Vec3::sReplicate(1.0f), filter, queryTransform, JPH::SubShapeIDCreator(), JPH::SubShapeIDCreator(), collector);

		if (!collector.HadHit())
		{
			printf("Test failed, womp womp\n");
		}
		else
		{
			printf("Test passed, woo!\n");
		}

These values were dumped straight from engine.

from joltphysics.

jrouwe avatar jrouwe commented on May 11, 2024

Ok, I can reproduce. The reason your shape wasn't deserializing is because you opened the file as a text file. Should have done:

std::ifstream myfile("my_collide.bin", ifstream::in | ifstream::binary);

Now onto finding out what goes wrong.

from joltphysics.

jrouwe avatar jrouwe commented on May 11, 2024

Ok, I should have seen this right away.

The issue is that sCastShapeVsShape expects inShapeCast to be relative to the center of mass of the shape that you cast against. So queryTransform is the center of mass transform of the shape you cast against, initialShapeCast contains the shape cast in world space (note that if your cast shape was not a box and had a center of mass offset then you would need to correct for it in mCenterOfMassStart), so the correct thing to do is indeed to transform initialShapeCast with the inverse of queryTransform to get it in the center of mass space:

JPH::ShapeCast shapeCast = initialShapeCast.PostTransformed(queryTransform.InversedRotationTranslation());

sCastShapeVsShape's inCenterOfMassTransform2 is only used to transform the hit results back into world space. So if you do:

JPH::CollisionDispatch::sCastShapeVsShape(shapeCast, settings, pShape, JPH::Vec3::sReplicate(1.0f), filter, JPH::Mat44::sIdentity(), JPH::SubShapeIDCreator(), JPH::SubShapeIDCreator(), collector);

then you're going to transform the hit point and normal by identity. So instead you should do:

JPH::CollisionDispatch::sCastShapeVsShape(shapeCast, settings, pShape, JPH::Vec3::sReplicate(1.0f), filter, queryTransform, JPH::SubShapeIDCreator(), JPH::SubShapeIDCreator(), collector);

so that the hit results passed to the collector will be in world space.

I'm going to see if I can make a helper function for this because the interface is a bit confusing.

from joltphysics.

Joshua-Ashton avatar Joshua-Ashton commented on May 11, 2024

I see, we were manually rotating/translating those after, seems weird for the func to work like this when you can seemingly do it yourself.

Also yeah, ifstream moment...

from joltphysics.

jrouwe avatar jrouwe commented on May 11, 2024

The sCastShapeVsShape is used recursively (so a compound shape calls it on its children). If we don't keep track of the current COM transform, you will get your hit results in the space of a random child and it will be difficult to get everything back in world space (it's not a matter of multiplying with queryTransform because then you miss the transform of the child).

Also CastShapeSettings::mActiveEdgeMovementDirection wouldn't work without knowing what the current COM transform is.

I've created #116 to make shape casting a little bit easier.

from joltphysics.

Joshua-Ashton avatar Joshua-Ashton commented on May 11, 2024

Thanks a lot! Will try it out later today.

Really appreciate all you have done so far!

from joltphysics.

jrouwe avatar jrouwe commented on May 11, 2024

I've merged #116 into master. Closing the ticket (reopen if you need anything else).

from joltphysics.

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.