Question

I am trying to draw an arrow from one mesh object to another mesh object. But if I directly use their postions and send as arguments in the Arrow Helper then the arrow is going inside the object because the position of an object means the centre of it.

So I created objects and I am using raycaster.

      var ray = new THREE.Raycaster(sourcePos, direction.clone().normalize());

SO here the origin is the Source objects's position and direction is the source to target direction. Then I am taking the collision results when I intersect with the target ie

      var collisionResults = ray.intersectObject(target);

Then I am calculating the distance at which the ray intersects the target for the first time:

      var length=collisionResults[0].distance;

Then, creating an arrow with the following arguments:

      var arrow = new THREE.ArrowHelper(direction.clone().normalize(), sourcePos, length, 0xaa0000);
      scene.add( arrow );

The arrows are getting created as expected for :

      helper_methods.draw_arrow(mesh1,mesh2);
      helper_methods.draw_arrow(mesh1,mesh2);

But for :

      helper_methods.draw_arrow(mesh2,mesh3);

It says " collisionResults[0] " is null. I am not able to figure out the reason . Any help is appreciated. Below is the snippet of code Iam using. I have also mentioned the helper methods:

var mesh1 = helper_methods.create_mesh();
mesh1.position.set(100,0,0);
scene.add( mesh1);

var mesh2 = helper_methods.create_mesh();
mesh2.position.set(300,0,0);
scene.add( mesh2);

var mesh3 = helper_methods.create_mesh();
mesh3.position.set(100,200,0);
scene.add( mesh3);


helper_methods.draw_arrow(mesh1,mesh2);
helper_methods.draw_arrow(mesh1,mesh2);
helper_methods.draw_arrow(mesh2,mesh3);

and the helper methods I am using :

create_mesh: function(){

var darkMaterial = new THREE.MeshBasicMaterial( { color: 0xffffcc } );
var geometry=new THREE.CylinderGeometry( 30, 30, 50,100,1 );
var mesh = new THREE.Mesh( geometry, darkMaterial );
return mesh;
},



draw_arrow: function(source,target){

var sourcePos = new THREE.Vector3(source.position.x, source.position.y, source.position.z);
var targetPos = new THREE.Vector3(target.position.x, target.position.y, target.position.z);
var direction = new THREE.Vector3().subVectors(targetPos, sourcePos);

var ray = new THREE.Raycaster(sourcePos, direction.clone().normalize());
var collisionResults = ray.intersectObject(target);
var length=collisionResults[0].distance;
var arrow = new THREE.ArrowHelper(direction.clone().normalize(), sourcePos, length,    0xaa0000);

scene.add( arrow );
return arrow;
Était-ce utile?

La solution

There is a simpler way to do this.

Method 1

  1. You're drawing from one point on the surface of one mesh to another point on the surface of another.
  2. You have the position of the center of the object, which means you have the position of the surface as well.
    • The vertices of your object are all centered around the origin (the local center)
    • The center of your object is transformed by the transformation matrix you give it.
    • What this really does is transform all of those vertex positions.
    • That vertex position is (still) on the surface, all you have to do is transform it.

Now, this works if you know which vertex you want to use, which it sounds like might be the case from how you asked your question. However, if you just want an arrow pointing from one mesh to the other without having it poking through the mesh, the next method may be better.

Method 2

If all you want to do is point from one mesh to another, and having a point exactly on the surface isn't important, this is the better method. What you do is calculate the bounding box or bounding sphere for your mesh and use that to quickly find how to draw your arrow.

  1. Generate a bounding volume

    a. When you read in all the vertices of your mesh, keep track of which one is farthest from the center. By the end, this will give you the radius of the sphere containing your mesh.

    b. You can instead keep track of the greatest distances in each of the 6 directions (+-x,y,z) to generate a bounding box.

  2. Calculate a line from the surface of the bounding volume to the surface of another. Now that you have either a box or a sphere, this should be very easy (especially for the sphere).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top