Jump to content

[SOLVED] Path drawing and tracking for target


photo

Recommended Posts

Hello everyone,

I would like to learn, path drawing and moving an object along this path direction with c++.Basically i have an object and target. These objects have collision mask for intersection.So i am able to move object according to center point of the camera view.When I point the middle point of the camera image to the target, the object moves towards the target and when they touch each other, a collision effect occurs. At this point i would like to move target and track it with center point of the camera.I want to draw a invisible path towards the target after a certain distance along the track and I want the object to follow this curved path towards the target.

//My object code , 
Unigine::NodePtr mObject;
Unigine::NodeReferencePtr tObject = Unigine::NodeReference::create("External/Entities/Object.node");
tObject->release();
Unigine::Editor::get()->addNode(tObject->getNode(),0);
mObject = tObject->getReference();
Objectplaysound();
mObject->setWorldPosition(mAnotherobjectforpos->getWorldPosition());
mObject->setWorldRotation(mAnotherobjectforpos->getWorldRotation());

Could you please explain and show me how to continue from this code.

Additional pictures are available below for better understanding.

Any help will be appreciated.

Cameraview1.png

Cameraview2.png

Link to comment

Hello,

I have to say I don't get the idea fully. Here's how I understood the task:

  1. You have two objects, lets keep your names: Object and Target
  2. You want to control Object with camera vector and point the direction just with camera movement (Is it already working in your application?)
  3. If you're "looking" at the Target the Object moves to the Target and collides
  4. As I understand you're talking about physical interaction
  5. After the collision Target starts to move. Do you mean that it was given an impulse after collision?
  6. When the Target is moving camera starts following it
  7. I didn't get the idea of an invisible path. Do you need it to be used as a trajectory or navigation path for the Object?
  8. After the collision the Object start following the Target by the same trajectory

Am I correct?

And why the trajectory on your image is curved/parabolic?

It would be great if you can give us a more practice-oriented example of what you're simulating here. The task looks abstract and a little obscure.

Thanks.

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Link to comment

1) Correct
2)We have invisible laser to the target and it extends along camera center to target.So Object should track target when i moved camera center point to the target.
3)Correct
4)There is already physical interaction between object and target.I just would like to implement tracking movement to object for target.But this movement should be close to real environment.Therefore i should integrate curved movement to object when the target position is changed and i pointed the camera center to the target.
5)Nope i don't need any physical interaction for this process.No need impulse
6)When the target is moving any position in environment, object should start to track it during pointing it with laser(camera center)
7) I think path idea is another way of making this task.Is it possible to draw path to target with random curved line? and yes something like trajectory or navigation of target to track for object.
8)No need, object and target explodes when they contacted each other.Object should move to target before this collision.

Additionaly i am able to get intersection point(vector) between object and target with laser.

Simply with

body->getContactPoint(num);//it returns contact point of laser and the target.So object should track this point(target point) with curvilinear movement.
Edited by burakdogancay
Link to comment

Hi burakdogancay,

I have one question: do you need to find a trajectory or do you need to draw a trajectory (do you have an array of points along this curve)?

If you want to find this, you can read this articles:
http://www.theappguruz.com/blog/create-homing-missiles-in-game-unity-tutorial
https://www.codeproject.com/Articles/19310/Hitting-a-Moving-Target-The-Missile-Guidance-Syste

If you want to draw this, you can use Visualizer:

int init()
{
	// enable visualizer
	Visualizer::get()->setEnabled(1);
	
	// ...
}

int update()
{
	// draw trajectory
	for (int i = 1; i < points.size(); i++)
		Visualizer::get()->renderLine3D(points[i - 1], points[i], vec4::WHITE);

	// ...
}


I want the object to follow this curved path towards the target
You can use our WorldSplineGraph / SplineGraph classes:
This method is useful for moving:
SplineGraph::calcSegmentPoint()

These methods are useful for rotation:
SplineGraph::calcSegmentTangent()
SplineGraph::calcSegmentUpVector()
Use it paired with lookAt (or setTo).

Best regards,
Alexander

Link to comment

Thank you for your response,What i want to do is directly available this link that alexander specified. http://www.theappguruz.com/blog/create-homing-missiles-in-game-unity-tutorial

Lets forget to draw path.I just would like to do homing missile movement.But given example of this link is implemented in unity, i just need to integrate it.

This is my object code:

Unigine::NodePtr mObject;
Unigine::NodeReferencePtr tObject = Unigine::NodeReference::create("External/Entities/Object.node");
tObject->release();
Unigine::Editor::get()->addNode(tObject->getNode(),0);
mObject = tObject->getReference();
Objectplaysound();
mObject->setWorldPosition(mAnotherobjectforpos->getWorldPosition());
mObject->setWorldRotation(mAnotherobjectforpos->getWorldRotation());

This is how i implement direct movement of object to the target(it just starts to move to object linearly in x axis).

mObjectMovSpeed = 20
direction =(Unigine::Math::Vec3) mLauncher->getWorldDirection(Unigine::Math::AXIS_X);
mObject->setWorldPosition(mObject->getWorldPosition()+direction*mObjectMovSpeed*Unigine::Game::get()->getIFps());

//So i should continue to this direct movement to add tracking.
//1)I know target position
//2)I know contact point thanks to the laser which is avilable on camera center
//3)I know object position
//4)I know object direction and target direction


         

I just couldn't implement unity code idea to my code.Could you please help me about it.Some functions are a bit hard to understand and implemet to unigine c++ code

like :

  • float rotateAmount=Vector3.Cross(direction,transform.up).z;

 

For example, the idea of http://www.theappguruz.com/blog/create-homing-missiles-in-game-unity-tutorial does not work like this,

 

Unigine::Math::Vec3 direction = objecttragetcontactpoint - mObject->getWorldPosition();
        direction.normalize();
        Unigine::Math::Vec3 rotateAmountVec3;
        Unigine::Math::cross(rotateAmountVec3,Objectforwarddirect,mObject->getTransform().getAxisZ());
        Unigine::Math::vec3 rotateAmount;
        Unigine::Math::mul(rotateAmount,Unigine::Math::vec3(1,1,-10),rotateAmountVec3);
        mObject->getObjectBodyRigid()->setAngularVelocity(rotateAmount);

 

Edited by burakdogancay
Link to comment

Could you please help me about it
I have written a sample code for you without physics (angularVelocity and linearVelocity):

#include <Unigine.h>

using namespace Unigine;
using namespace Math;

// ...

float mObjectMovSpeed = 20;
Vec3 direction = (Unigine::Math::Vec3) mLauncher->getWorldDirection(Unigine::Math::AXIS_X);
mObject->setWorldPosition(mObject->getWorldPosition() + direction*mObjectMovSpeed*Unigine::Game::get()->getIFps());

//So i should continue to this direct movement to add tracking.
//1)I know target position
//2)I know contact point thanks to the laser which is avilable on camera center
//3)I know object position
//4)I know object direction and target direction

float mObjectRotSpeed = 30; // degrees per second
Vec3 dirToTarget = normalize(mTarget->getWorldPosition() - mObject->getWorldPosition());
	
// calculate target rotation
// where X is forward and Z is up
vec3 x, y, z;
vec3 up = vec3::UP;
x = dirToTarget;
cross(y, up, x).normalize(); // get "left" axis
cross(z, x, y).normalize(); // get "up" axis
quat target_rotation = quat(x, y, z);

// rotate object to target
mObject->setWorldRotation(rotateTowards(mObject->getWorldRotation(), target_rotation, mObjectRotSpeed * Game::get()->getIFps()));

 

Link to comment

Thank you so much, it works well but there is one small problem.It starts to track object according to target point, but head of the object directly rotate to the target.

Its head should rotate slightly to the target.I couldn't solve it.

Thank you for your help, my best wishes and have a good day.

Link to comment

Hi burakdogancay,

Its head should rotate slightly to the target.I couldn't solve it.
I think there are two simple ways:
1) Decrease mObjectRotSpeed value
2) Use maximum accuracy:

// rotate object to target
float maximum_accuracy = 10; // degrees
if (Math::getAngle(mObject->getWorldRotation(), target_rotation) > maximum_accuracy)
{
	mObject->setWorldRotation(rotateTowards(mObject->getWorldRotation(), target_rotation, mObjectRotSpeed * Game::get()->getIFps()));
}

 

Best regards,
Alexander

Link to comment

Unfortunately it does not work now, it seems to be working but it does not act when we put target to the long range and give it a movement.Then i try to track it with camera center, unfortunately object turns around but does not move to target :(

According to our test, it does not act as our assumption :(

Edited by burakdogancay
Link to comment

Hi burakdogancay,

Object turns around but does not move to target :(
Is there any other idea ?

I don't see where you move your object to the target. In your previous post:

float mObjectMovSpeed = 20;
Vec3 direction = (Unigine::Math::Vec3) mLauncher->getWorldDirection(Unigine::Math::AXIS_X);
mObject->setWorldPosition(mObject->getWorldPosition() + direction*mObjectMovSpeed*Unigine::Game::get()->getIFps());

I see "mLauncher". What is it? Does it constantly rotate on the target?
If no, use this:

float mObjectMovSpeed = 20;
Vec3 direction = normalize(mTarget->getWorldPosition() - mObject->getWorldPosition());
mObject->setWorldPosition(mObject->getWorldPosition() + direction * mObjectMovSpeed * Unigine::Game::get()->getIFps());



Best regards,
Alexander

Link to comment

mLauncher is the mobject parent.It is avaliable on my vehicle and rotates around , so mObject is added to mlauncher. If mLauncher rotates,mobject rotates with it. so i should get X axis of the mlauncher to move object in forward direction. So above code just rotates object around and does not move to target point, it directly moves forward as before with rotating around.Also i dont want to rotate around , it should rotate its head to target and start to move target point.

The code is like this now.

 

Unigine::NodePtr mObject;
Unigine::NodeReferencePtr tObject = Unigine::NodeReference::create("External/Entities/Object.node");
tObject->release();
Unigine::Editor::get()->addNode(tObject->getNode(),0);
mObject = tObject->getReference();
Objectplaysound();
mObject->setWorldPosition(mAnotherobjectforpos->getWorldPosition());
mObject->setWorldRotation(mAnotherobjectforpos->getWorldRotation());

mObjectMovSpeed = 20
direction =(Unigine::Math::Vec3) mLauncher->getWorldDirection(Unigine::Math::AXIS_X);//Forward direction according to launcher
mObject->setWorldPosition(mObject->getWorldPosition()+direction*mObjectMovSpeed*Unigine::Game::get()->getIFps());

//This below part is yours but it rotates around and does not affect object forward position according to m launcher x axis (it just rotates around).So i need to rotate and move it to the target something like homing missile

     float maximum_accuracy = 10;
        Unigine::Math::Vec3 dirtotarget = Unigine::Math::normalize(targetpointvector - mObject->getWorldPosition()); //target point vector is the contact point of laser and target, so it represents target point
        Unigine::Math::vec3 x, y, z;
        Unigine::Math::vec3 up = Unigine::Math::vec3::UP;
        x=(Unigine::Math::vec3)dirtotarget;
        Unigine::Math::cross(y, up, x).normalize(); // get "left" axis
        Unigine::Math::cross(z, x, y).normalize(); // get "up" axis
        Unigine::Math::quat target_rotation = Unigine::Math::quat(x, y, z);


        if(Unigine::Math::getAngle(mObject->getWorldRotation(), target_rotation) > maximum_accuracy){
            qDebug()<<"ANGLE OF MISSILE : "<<Unigine::Math::getAngle(mMissileKornetLeft->getWorldRotation(), target_rotation);

        mObject->setWorldRotation(Unigine::Math::rotateTowards(mObject->getWorldRotation(),target_rotation,5*Unigine::Game::get()->getIFps()));
        }

 

Edited by burakdogancay
Explanations
Link to comment

Hi burakdogancay,

mLauncher is the mobject parent
I don't understand why did you attach the mObject to the mLauncher (and... I don't see any setParent() method in your code). If this is true it will not work. The mObject must not have parent.

Can you provide a full working sample with this problem? I can't help with the given piece of code.


Best regards,
Alexander

Link to comment

Ok i will give you all details;

I have 3 main object which is available under a main node(player) in editor.They are named as,

1)mBody : It is main body
2)mTurret : this is the turret of the body, 
3)mLauncher : This one is a launcher that will include mObject inside(So mostly we are going to work on this one, for mobject operation)

Here is the details of the code with explainations;

//INITIALIZATION
NodePtr mBody = Util::Search::getNodeRecursive("Body", mReference->getNode()); //Simply get nodes by name which is available in editor 
NodePtr mTurret = Util::Search::getNodeRecursive("Turret", mReference->getNode());
NodePtr mLauncher = Util::Search::getNodeRecursive("Launcher", mReference->getNode());

//Under mLauncher there is disabled node to set mobject on its position
NodePtr mObjectref = Util::Search::getNodeRecursive("mObjectref",mLauncher);

//UPDATE(MOVEMENT)

Unigine::NodePtr mObject;
Unigine::NodeReferencePtr tObject = Unigine::NodeReference::create("External/Entities/Object.node");//Dont worry, I dont create it everytime, i create object only once, all works well just homing missile process is required
tObject->release();
Unigine::Editor::get()->addNode(tObject->getNode(),0); //adds object to editor
mObject = tObject->getReference(); //assign it to mObject

mObject->setWorldPosition(mObjectref->getWorldPosition());//set its position and rotation according to mobjectref from above and it is also under of mlauncher as initialization code
mObject->setWorldRotation(mObjectref->getWorldRotation());

//MOVEMENT FUNCTION OF THE OBJECT
mObjectMovSpeed = 20
direction =(Unigine::Math::Vec3) mLauncher->getWorldDirection(Unigine::Math::AXIS_X);//Forward direction according to mlauncher, I should get its direction because it rotates arond and mobject should rotate with it.
mObject->setWorldPosition(mObject->getWorldPosition()+direction*mObjectMovSpeed*Unigine::Game::get()->getIFps());// It moves directly to the target(Center point of the camera)according to x axis of mlauncher 

//SO BELOW PART IS THAT YOU SPECIFIED, WHAT I WOULD LIKE TO DO IS TO TRACK TARGET, I CAN DETECT IT EVERYTIME AND GET ITS POSITION JUST HOMING MISSILE MOVEMENT IS REQUIRED
//it rotates around and does not affect object forward position according to m launcher x axis (it just rotates around).So i need to rotate and move it to the target something like homing missile

     float maximum_accuracy = 10;
        Unigine::Math::Vec3 dirtotarget = Unigine::Math::normalize(targetpointvector - mObject->getWorldPosition()); //target point vector is the contact point of laser and target, so it represents target point
        Unigine::Math::vec3 x, y, z;
        Unigine::Math::vec3 up = Unigine::Math::vec3::UP;
        x=(Unigine::Math::vec3)dirtotarget;
        Unigine::Math::cross(y, up, x).normalize(); // get "left" axis
        Unigine::Math::cross(z, x, y).normalize(); // get "up" axis
        Unigine::Math::quat target_rotation = Unigine::Math::quat(x, y, z);


        if(Unigine::Math::getAngle(mObject->getWorldRotation(), target_rotation) > maximum_accuracy){
            qDebug()<<"ANGLE OF OBJECT : "<<Unigine::Math::getAngle(mObject->getWorldRotation(), target_rotation);

        mObject->setWorldRotation(Unigine::Math::rotateTowards(mObject->getWorldRotation(),target_rotation,5*Unigine::Game::get()->getIFps()));
        }

 

Edited by burakdogancay
Link to comment

Hi burakdogancay,

As i said, the mObject must not have a parent (otherwise it will not work). I've rewritten my code and made a small sample.
Is that how it should work? Download the attachment to look at the code and content.

image.png

int AppWorldLogic::init()
{
	mObject = Editor::get()->getNodeByName("mObject");
	mLauncher = Editor::get()->getNodeByName("mLauncher");
	target = Editor::get()->getNodeByName("target");

	// detach mObject from the mLauncher to rotate it independently
	mObject->setWorldParent(NodePtr());

	Visualizer::get()->setEnabled(1);

	return 1;
}

int AppWorldLogic::update()
{
	float ifps = Game::get()->getIFps();

	// move target
	target->setWorldPosition(target->getWorldPosition() + Vec3(target->getWorldDirection(AXIS_Z) * 3.0f) * ifps);

	// look at target
	Vec3 targetpointvector = target->getWorldPosition();
	mLauncher->setWorldDirection(vec3(targetpointvector - mLauncher->getWorldPosition()).normalize(), vec3::UP, AXIS_NZ);
	
	Visualizer::get()->renderLine3D(mLauncher->getWorldPosition(), mLauncher->getWorldPosition() + Vec3(mLauncher->getWorldDirection(AXIS_X) * 1.0f), vec4(1, 0, 0, 1));
	Visualizer::get()->renderLine3D(mLauncher->getWorldPosition(), mLauncher->getWorldPosition() + Vec3(mLauncher->getWorldDirection(AXIS_Y) * 1.0f), vec4(0, 1, 0, 1));
	Visualizer::get()->renderLine3D(mLauncher->getWorldPosition(), mLauncher->getWorldPosition() + Vec3(mLauncher->getWorldDirection(AXIS_Z) * 1.0f), vec4(0, 0, 1, 1));
	Visualizer::get()->renderLine3D(mLauncher->getWorldPosition(), mLauncher->getWorldPosition() + Vec3(mLauncher->getWorldDirection(AXIS_NZ) * 1.5f), vec4(1, 1, 1, 1));

	// move homing missile
	float mObjectMovSpeed = 6.0f;
	Vec3 direction = Vec3(mLauncher->getWorldDirection(AXIS_NZ));
	mLauncher->setWorldPosition(mLauncher->getWorldPosition() + direction * mObjectMovSpeed * ifps);
	mObject->setWorldPosition(mLauncher->getWorldPosition());

	float maximum_accuracy = 4;
	Vec3 dirtotarget = normalize(targetpointvector - mObject->getWorldPosition());
	vec3 x, y, z;
	vec3 up = vec3::UP;
	z = -(vec3)dirtotarget;
	cross(x, up, z).normalize(); // get "right" axis
	cross(y, z, x).normalize(); // get "up" axis
	quat target_rotation = quat(x, y, z);

	float angles_per_second = 360.0f;
	if (getAngle(mObject->getWorldRotation(), target_rotation) > maximum_accuracy)
		mObject->setWorldRotation(rotateTowards(mObject->getWorldRotation(), target_rotation, angles_per_second * ifps));

	// check detection
	if ((mObject->getWorldPosition() - targetpointvector).length() < 1.0)
	{
		// reset
		mLauncher->setPosition(Vec3::ZERO);
		target->setWorldPosition(Vec3::ZERO);
		target->setRotation(quat(Game::get()->getRandomFloat(-70.0f, 70.0f), Game::get()->getRandomFloat(-70.0f, 70.0f), 0));
	}

	return 1;
}


Best regards,
Alexander

homing_missile.zip

Link to comment

Alexander, thank you for your help and interest.The code that you specified is really useful and i utilized some part of it.Have a nice day and apologize for time consuming.

Edited by burakdogancay
Link to comment
  • silent changed the title to [SOLVED] Path drawing and tracking for target
×
×
  • Create New...