Open ghost opened 4 years ago
Can you show me the code? void*
will almost certainly not work directly, if that's what you're suggesting.
Hi, I don't know if you know the bullet physics library but in it you can attach to an collision object something called user pointer which is of type void*. This scenario helps you when you have a collision and you want to retrieve that object and do something with it, of course you will have to cast it to your object type.
How I can send a new created entity (ex: auto entity = _ecs.entities.create(); ) to that pointer, without being invalid when I want to retrieve it back.
Thanks.
Ah, okay. You'll probably want to use the numeric id of the entity instead, as Entity objects are transient values.
Also if that still doesn't help, first rule of bug reports is to provide as much information as possible: sample code, error messages, etc.
Ok, thanks @alecthomas I will come with the back with the code and the messages.
Hi @alecthomas, I got an working solution:
I send the id to the physics in this way: auto body = new btRigidBody(info); body->setUserIndex(entity.id().id()); // this is just an int
And I get it in this way: auto id = _ecs.entities.create_id(hit.m_collisionObject->getUserIndex()); auto entity = _ecs.entities.get(id);
I did not know about that create_id method which is very helpful.
Can I do a pull request with an operator uint64_t for the Entity::Id? it will be nice to avoid this entity.id().id() and use just entity.id() instead.
Thanks.
I am not sure, is a question: Why you use "uint64_t" instead "Entity::Id" ? Both looks copyable, and second case your call is more readable: "entity.id()" also you don't need use "create_id", you can use "get" directly.
Sorry to hop onto this thread, but I think my issue is similar -- I'm using NVIDIA's PhysX as my physics engine. The engine leaves rigid body actors with a field void* userData
that can be used to connect PhysX engine objects with user application objects. documentation is here.
Along the same lines as @iamAdrianIusca , I'm trying to link an entity to this void*
pointer. Bullet supports setUserIndex
which stores an int
, so I think an entity.id()
makes sense -- but is there any way that I can store a pointer that links back to an entity as well? This would be the same as bullet's setUserPointer
function.
It seems like most of EntityX's types are not pointers, but are essentially custom handles, or static IDs that I can't link a pointer to.
That is 100% correct. Assuming your machine word size is 64-bit you could store the Entity ID in the void*
directly.
Ah, got it!
So I should store the integer ID number into the pointer via:
physx_object->userData = (void*)(entity.id().id());
It can't be dereferenced like a true pointer, but can be brought back with:
auto entity = _ecs.entities.get((uint64_t)(physx_object->userData));
thanks!
Nice morphogencc, I do something different (more complex maybe), and works with 32 bits.
struct IntrospectionComponent : public entityx::Component<IntrospectionComponent>
{
std::string type;
entityx::Entity::Id id;
};
Is a component for know, who am I ? (introspection).
In your "PhysX"->userData you can write something like this:
void set_userdata(PhysXSomeone& node, IntrospectionComponent& introspection)
{
node->userData = (void*)&introspection;
}
You need a system for fill introspection values (only one time, I use PhysicsDescription like "flag component"):
es.each<Transform, PhysicsDescription, IntrospectionComponent>([&](entityx::Entity entity, Transform& transform, PhysicsDescription& physics_desc, IntrospectionComponent& introspection)
{
introspection.id = entity.id();
bool is_projectile = entity.has_component<ProjectilComponent>();
if (is_projectile)
{
introspection.type = "projectil";
}
else // is enemy
{
introspection.type = "insect";
}
entity.assign<plague::PhysicsComponent>(.......); // create physics using "PhysicsDescription"
entity.component<PhysicsDescription>().remove();
});
Yo can recover entity:
auto obj = static_cast<plague::IntrospectionComponent*>(node_physx->userData);
auto entity = entities.get(obj->id);
And Finally, when I have collisions, for example, now I can read your userData:
auto objA = static_cast<plague::IntrospectionComponent*>(physx_node->userData);
auto objB = static_cast<plague::IntrospectionComponent*>(physx_node->userData);
if (objA->type == "projectil" && objB->type == "insect")
{
// do something
}
Hi @alecthomas , great library!
I have a scenario in one of my projects, where I need to pass an entity or a component to the physics engine (bullet) as a pointer (void*).
When I am trying to receive the pointer back, if I cast it to an entity for example, I can't access any of the components because It gives me some error like the id is invalid or if I am trying to use the id it tells me that the index is smaller than the component mask (or something close to this).
Is there any other way to pass an entity as a pointer and access it in some other part of the code without being invalid?
Thanks.