Jump to content

Collision effects for.node(fbx) files


photo

Recommended Posts

Hello everyone,

I would like to ask, is there any way to provide collision between two nodes? I added two objects as ".node"(FBX) file and tried to set collider on them.But unfortunately I couldn't check any collision is available between them.According to this collision I would like to give some effect like explosions on objects. 

simply,

Unigine::NodePtr node1;
Unigine::NodePtr node2;

then I initialize node objects for them which is available in Unigine editor,mReference represent parent node(everything works and I can show them in Unigine engine(these two objects are available on the screen))

node1 = Util::Search::getNodeRecursive("Body", mReference->getNode());
node2 = Util::Search::getNodeRecursive("Turret", mReference->getNode());

then,

I set collider for second object and first object,

node1.setCollider(1);
node2.setCollider(1);

then,
I move node1 to the node 2 object in for loop.

node1.setPosition(Vec3) // it starts to move second object

 

But unfortunately I don't know how to check they touch each other or not.Simply node1 passes node2 and goes away.(There is no tutorials for Node collision)

Any help would be appreciated.

 

Link to comment

Hi Burak,

Setting just the collider flag for the two objects is not enough. Two types of collisions are supported:

  • Shape - Shape
  • Shape - Surface

So, at least one of your objects must have a physical body and shape assigned. This article explains how collision detection works in UNIGINE.

This usage example about selective collision detection might be helpful.

If you want to perform certain actions in case of collision, try this usage example.

Hope this helps!

BTW, a new Physics video tutorial is on the way, stay tuned!

Thanks!

Link to comment

I already checked all tutorials related to collision.But unfortunately I don't know how create mesh and assign body to node.Other examples just show creating box and apply collision mask to these boxes or plane.But I have 3d models as node which is designed by me.So how can I create surface or body for them to enable collision detection.

 

I need just an example to understand for node process for collision.I have to surround my 3d models with body but how ?

Edited by burakdogancay
Link to comment

Ok, I see...

So, let's start with basics!

Suppose You import a couple of FBX models and want to detect collisions for them as they are driven by physics.

Let's consider the simplest way, this would require a couple of optimizations - select each of your FBX assets in the Asset Browser and enable the following Mesh Import Options  in the Parameters window (see the image):

  • Merge Static Meshes
  • Merge Surfaces By Materials

And click Reimport.

s_cd_1.png

For more information you can check out our video tutorial on Importing 3d Models.

So, now you've got optimized meshes (your models) and we can get to collisions.

The first thing is that you can only assign a body to an object (not just any node). Objects have surfaces, so you can use them as static colliders (that is a Shape - Surface collision). In your case a Shape - Shape collision detection is probably the best option. So, we'll have to assign physical bodies and collision shapes to your models.

A surface is a part of your model's geometry, so all surfaces are already created as you import your model to UNIGINE.

Now, drag FBXes corresponding to your models to the Scene Viewport from the Asset Browser and place them where you want. Find your first model in the World Hierarchy window and select it, check out node type in the Parameters window (most likely it'll be ObjectMeshStatic).

s_cd_2.png

Now, that you have your first object selected switch to the Physics tab in the Parameters window.

Here assign a body to your object by selecting Rigid in the Type dropdown.

s_cd_3.jpg

Now, after adding a body, you can a collision shape(add at least one ), let it be a box - select Box and click Add.

s_cd_4.png

Repeat the same for the second object and both objects will have bodies and shapes assigned to them. Don't forget to save your world.

You can also perform body and shape assignment via code like this:

// getting a pointer to the node with a given name (make sure that it is a Mesh Static Object)
NodePtr node = Editor::get()->getNodeByName(object_name);
if (node)
{
     // downcasting node to ObjectMeshStaticPtr
	ObjectMeshStaticPtr object = ObjectMeshStatic::cast();

	// assigning a rigid body with our object
	BodyRigid::create(object->getObject());
		
	vec3 size; //<-- specify shape size here
      
	// creating a box shape of the desired size and assigning it to the rigid body of our object
	object->getBody()->addShape(ShapeBox::create(size)->getShape(), translate(0.0f, 0.0f, 0.0f));
}

Hope this helps!

This article might be useful for better understanding of UNIGINE's basics.

Thanks!

Link to comment

Thank you for your response I understood the issue clearly. I applied all configurations for box 1 and I evaluated(Basically it seems to be applied).But unfortunately the program crashes when I add these configurations to node reference.

Unigine::NodeReferencePtr node;
Unigine::ObjectMeshStaticPtr mTargetmesh;

 

QString tPath = QString("%1/Entities/OTHER/%2.node").arg(Util::BData::ig.ExternalDir).arg(tInfo.node);
qDebug()<<"Added Node:"<<tPath;
node = Unigine::NodeReference::create(tPath.toStdString().c_str());

 

if(node.get()){
            qDebug()<<"Node Name : "<<node->getNodeName();

 

 

 
            mTargetmesh = Unigine::ObjectMeshStatic::cast(node->getNode());
            mTargetmesh->getBody()->addShape(Unigine::ShapeBox::create(Unigine::Math::vec3(0.1f))->getShape(), Unigine::Math::translate(0.0f, 0.0f, 0.0f));

 
        }
Edited by burakdogancay
Link to comment

The point is that you're actually trying to cast a NodeReference to an ObjectMeshStatic which is incorrect, as it is not a static mesh object, it is a node reference - casting doesn't work that way! This obviously leads to a crash.

Moreover, you're trying to get a body without creating and assigning it first - that would be a second crash cause in the future.

The .node file usually contains a pre-fabricated node (or a hierarchy of nodes) with all the materials and properties that are required for its rendering. All changes that are made for the node reference via UnigineEditor are saved into this file. A NodeReference just refers to this file, so basically it can contain hierarchy of different types of nodes including lights, decals, etc. Asigning a body and shape to a hierarchy of nodes is not possible - you can assign a body to an object only - one body to one object (please be aware, that not all nodes are objects actually, that's why I gave you a link to the list of objects above).

To get a node or node hierarchy, to which a NodeReference refers, you should use the NodeReference::getReference() method:

// create a NodeReference instance
NodeReferencePtr nodeRef = NodeReference::create("mynoderef.node");
// get a node stored by the reference
NodePtr node = nodeRef->getReference();
// if the node is a NodeDummy
if (node->>getType() == Node::NODE_DUMMY){
	// print the type name of each child node of the root node stored by the reference 
	for(int i = 0; i & node->getNumChildren(); i++) {
		Log::message("%d: %s\n",i,node->getChild(i)->getTypeName());
	}
}

So, you should first find an object (e.g. an ObjectMeshStatic in our case) in the hierarchy , and as you find it, add a body and shape to it (make sure that there is a single ObjectMeshStatic in the hierarchy, otherwise you'll end up with a separate physical body for each static mesh in the hierarchy):

// if the node is an ObjectMeshStatic
if (node->>getType() == Node::OBJECT_MESH_STATIC){
    // downcast node to ObjectMeshStaticPtr
	ObjectMeshStaticPtr object = ObjectMeshStatic::cast(node);

	// first, assign a rigid body with our object 
	BodyRigid::create(object->getObject());
		
	vec3 size; //<-- specify shape size here
      
	// then create a box shape of the desired size and assign it to the rigid body of our object
	object->getBody()->addShape(ShapeBox::create(size)->getShape(), translate(0.0f, 0.0f, 0.0f));
}

Thanks!

Link to comment

First of all I would like to thank you for your interest and help. I added everything correctly according your instruction and I am able to see they touch each other.

But I have to check collision according to above example with collision mask.

Simply I added ;

object1->getbody()->getShape(0)->setCollisionMaks(1); // Object1 is objstaticmesh with rigidbofdyand shapebox as object2

object2->setCollisionMask(1,0);

So I need an if condition to enable collision explosition effect.I don't know is there any function that checks them touch like;

if(collisiondetetcted)

{

Unigine::NodeReferencePtr texptarget = Unigine::NodeReference::create("Effects/targetexplosition.node");

}

 how can I check they really hit each other instead of "collisiondetection" in if condition.

Edited by burakdogancay
Link to comment

You're welcome, Burak!

You can process collisions via callbacks by setting a contact callback function for a physical body via the Body::addContactCallback() method (see method's description), the Playing Sounds on Collisions example, that I mentioned above should help!

On 7/4/2019 at 2:54 PM, fox said:

If you want to perform certain actions in case of collision, try this usage example.

Thanks!

Link to comment
×
×
  • Create New...