Giter VIP home page Giter VIP logo

Comments (15)

jrouwe avatar jrouwe commented on May 23, 2024 1
  1. The ConvexHullShapeSettings / MeshShapeSettings are only needed for cooking. Create() returns a Result object which lets you know if anything failed. If it didn't fail you can call Get() to get your shape (store it in Ref!). After that the settings object can be deleted as all the data is stored in the shape.

For an example on how to serialize the Settings objects look at LoadSaveSceneTest::Initialize (if you have your own data format to store the original data I would not recommend using it).

The cooked data can be saved as shown in LoadSaveBinaryTest::Initialize (you can save an individual shape through Shape::SaveWithChildren). Note that the example uses an ostream but SaveBinaryState uses StreamOut which does not require you to use STL. Note that the binary serialization format can change with every library version and I don't provide a way of reading previous versions (rely on your own data formats!).

from joltphysics.

jrouwe avatar jrouwe commented on May 23, 2024 1
  1. The convex hull shape has a limit of 256 vertices AFTER hull generation (so you can provide as many internal points as you want). As said the Create() function will return an error if something went wrong.

from joltphysics.

jrouwe avatar jrouwe commented on May 23, 2024
  1. The data of the mesh shape is stored in a compressed format (not in a simple vertex / index format) so you have to go through GetTrianglesNext() in order to get the data. The Shape::Stats class was not designed to tell you up front the amount of triangles you're going to get, but I could take a look if that would work or not. In any case, just keep calling GetTrianglesNext() and enlarge your buffer for the time being.

from joltphysics.

jrouwe avatar jrouwe commented on May 23, 2024
  1. PhysicsMaterials are refcounted objects, you can share them between shapes. A shape will take a reference on it (it gets copied from the settings object to the shape). You cannot however make 1 convex hull and then give it to body 1 with material 1 and to body 2 with material 2. That would require making 2 convex hulls.

from joltphysics.

jrouwe avatar jrouwe commented on May 23, 2024
  1. As said the data is a compressed format that is not of the form shared vertices/indices.

from joltphysics.

jrouwe avatar jrouwe commented on May 23, 2024
  1. Yes that's an inconsistency. It doesn't matter much since it is only a cooking interface. You throw the settings object away afterwards. The reasoning was that Vec3 has much more support functions so is easy to use, Float3 is smaller and since a mesh has many more vertices than a convex hull I used Float3 there.

from joltphysics.

jankrassnigg avatar jankrassnigg commented on May 23, 2024

Thanks for all the answers, that's very helpful. Regarding 4) that seems to have been an oversight on my end, I just saw that on the shape I can change the material, I assumed that ALL shapes created from the same settings object would use the same material. All good then!

from joltphysics.

jankrassnigg avatar jankrassnigg commented on May 23, 2024

Actually, looking a bit more closely, 4) wouldn't work as I want it to work, since the ShapeSettings object caches the shape internally and always gives out the same shape object. Thus changing the material would affect all bodies that have that shape. I am not 100% happy with the design decision here, that baking a mesh and instantiating it as a shape are the same thing. I'd prefer it if the mesh data (convex or triangle mesh) would be one (ref-counted) object, and the shape would be a separate (ref-counted) object, which references the mesh data and stores the material pointer, the user data etc. This way one could instantiate the same mesh multiple times but with different runtime behavior.

That just made me realize, that my current code is wrong, because I need different user data for every shape instance. E.g. if I instantiate the same barrel three times, each shape needs to have different user data, such that when I raycast against it, I can map that back to the proper game object. I want to have that per-shape, rather than per-body so that I can detect whether a specific piece of the object was hit.

By calling ConvexHullShapeSettings::Create() I had assumed I get a new shape object every time (it is called "Create" after all), but it always returns the same object, so this wouldn't work. It's also not mentioned in the comments anywhere that "Create" may give you a cached object.

The only work around would be to do "new ConvexHullShape" myself to make sure I get dedicated shape instances, but than I run into the problem that convex hull generation is done in the shape constructor over and over.

from joltphysics.

jrouwe avatar jrouwe commented on May 23, 2024

I would use the user data of the body to tag the different instances of the barrels (that's what we do). You can collect it in the CollisionCollector::OnBody callback. If you're working with a compound you can have another user data (GetCompoundUserData) to identify which part it is.

Alternatively you could create a DecoratedShape which only purpose is to have a user data (e.g. OffsetCenterOfMassShape), but that will come at a perf cost.

from joltphysics.

jankrassnigg avatar jankrassnigg commented on May 23, 2024

If you're working with a compound you can have another user data (GetCompoundUserData) to identify which part it is.

Alternatively you could create a DecoratedShape which only purpose is to have a user data

Both interesting options that I have to look into more closely.

I already use the body user data as well. Here is an example:

In our engine we have "actor" components (static / dynamic / trigger) and shape components (sphere / box / triangle mesh / convex mesh / etc). An entity with an actor component will gather all shape components attached to it or it's children and create one Jolt body and set it's shape. If necessary, it uses compound shapes, RotatedAndTranslated decorators and so on.

When I do a raycast against that object, the raycast returns a handle to the actor component and the exact shape component that was hit. The user data on the Jolt body is used to know the actor component and the user data on the hit Jolt shape is used to map to the shape component.

Something like a projectile can then use this information to trigger an "on hit event" and provide the game logic with the information which actor and shape were hit.

I have used this for example to build a gas cylinder that you can shoot. It consists of two shapes, a shape for the body and another shape for the tip. If you shoot the body, the object explodes, if you shoot the tip (the valve), it starts flying off (good old Half-Life 2 gameplay).

In the physics engine this is supposed to be one body, but I only want the main shape to create collision contacts (since the valve shape is extra large so that people can hit it). That's why I'm wondering whether there is a way to have collision layers per shape.

And that's also why it is inconvenient to have the convex shape fully shared. But I'll check out if I can wedge something in between to override the user data. It just feels like a work-around for the fact that baked convex and triangle mesh data isn't a separate thing.

from joltphysics.

jankrassnigg avatar jankrassnigg commented on May 23, 2024

Alternatively you could create a DecoratedShape which only purpose is to have a user data

I have now successfully used that to share the same convex mesh among many bodies, with custom shape user data and a custom material pointer for each. It's actually a decent solution. Might even be a useful built-in decorator shape.

I want to do the same for triangle meshes and I want to be able to override the material slots. I thought in my decorator I could check whether the inner shape is a MeshShape, cast the pointer, compute the face/material index and then redirect the lookup, but looking at MeshShape::GetMaterial, it uses a private function DecodeSubShapeID. I guess I could copy that, but is there a better way maybe?

from joltphysics.

jankrassnigg avatar jankrassnigg commented on May 23, 2024

Oh and one minor pitfal I encountered: Shape::GetCenterOfMass should either be pure virtual, or have a pass-through implementation on the DecoratedShape base class. Currently decorators by default use the base implementation, which returns zero. I only noticed that once compound shapes came into play (and I have a visualizer for convex decomposition shapes). Otherwise it's easy to miss and might be tricky to figure out what exactly is wrong.

from joltphysics.

jankrassnigg avatar jankrassnigg commented on May 23, 2024

Ok, I went ahead and implemented the material override for triangle meshes as well, and it works quite nicely. Here is my code:

https://github.com/ezEngine/ezEngine/blob/d0fa0d52605f7738255790ccebd37f04e8dd59a6/Code/EnginePlugins/JoltPlugin/Shapes/Implementation/JoltCustomShapeInfo.cpp#L13

This is a bit hacked, though. I made DecodeSubShapeID public and copied some internal code over. Let me know whether this could be achieved a bit cleaner.

from joltphysics.

jrouwe avatar jrouwe commented on May 23, 2024

Oh and one minor pitfal I encountered: Shape::GetCenterOfMass should either be pure virtual, or have a pass-through implementation on the DecoratedShape base class.

Thanks for letting me know, I've just submitted a change that passes it through to the DecoratedShape.

I've also created #117 to make it possible for you to access the material index of a sub shape ID.

from joltphysics.

jankrassnigg avatar jankrassnigg commented on May 23, 2024

Awesome, thank you :)

I think by now I've been able to solve all the things in this issue.

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.