Check if camera can see a specific mesh.

Software: Away3D 4.x

Fragilem17, Newbie
Posted: 07 February 2013 10:36 AM   Total Posts: 15

Hi,

i succeeded in overlaying displayobjects (labels) on top of a model, so when you rotate the model they all follow along nicely. for this we added small planes in the 3D model in max, i iterate over the children of the loader (awd) to find those with a specific naming. these planes are then used to get the stage coordinates on each frame so the displayobjects can be placed correctly.

So far so good.

Now off course all planes that are hidden to the camera also have their displayobjects drawn. (see image)

How can i check whether the small plane is obscured from the camera’s view by some other geometry?

any help would be greatly appreciated!

 

   

Babylon, Jr. Member
Posted: 08 February 2013 05:34 AM   Total Posts: 39   [ # 1 ]

Greetings,

So the model rotates in a circle 360 degrees? Perhaps you could say if object model is rotated between x and y degrees, show this label, else it’s blocked by the model?

I’m a newb. Good luck

-B

 

   

Fragilem17, Newbie
Posted: 08 February 2013 09:20 AM   Total Posts: 15   [ # 2 ]

found it.
for future reference.
the term you would be searching for in this case is rayCasting!

_pickingCollisionVO _raycastPicker.getViewCollision(hotspot.xhotspot.y_view);
if (
_pickingCollisionVO && _pickingCollisionVO.entity == _productModel.productMesh{
 hotspot
.hide();
}else {
 hotspot
.show();

 

   

_kihu, Jr. Member
Posted: 12 February 2013 08:36 AM   Total Posts: 43   [ # 3 ]

This is awesome. I just had to set mouseEnabled = true for the objects I want to check.

 

   

Fragilem17, Newbie
Posted: 12 February 2013 02:42 PM   Total Posts: 15   [ # 4 ]

yes indeed, forgot to mention that. the objects should ‘listen’ for the ray. just like in mousePicking where you need to set the mouseEnabled = true also.

 

   

mb85, Newbie
Posted: 08 May 2013 04:30 PM   Total Posts: 14   [ # 5 ]

Apologies for bringing up an old thread but just wanted to thank you Fragilem17 - I spent a couple hours trying Ray.intersectSphere and other wrong approaches. This thread solved all my issues.

 

   

drbii, Member
Posted: 22 December 2014 09:45 PM   Total Posts: 72   [ # 6 ]
Fragilem17 - 08 February 2013 09:20 AM

found it.
for future reference.
the term you would be searching for in this case is rayCasting!

_pickingCollisionVO _raycastPicker.getViewCollision(hotspot.xhotspot.y_view);
if (
_pickingCollisionVO && _pickingCollisionVO.entity == _productModel.productMesh{
 hotspot
.hide();
}else {
 hotspot
.show();


Hi Fragilem17,
This thread is old, so I hope you see this.  Can you explain your code a little?  I’m trying to overlay labels on my model and want them to hide when the object is not in view.  I can’t seem to grasp how this works?  Thanks!
Dan

 

   

drbii, Member
Posted: 21 January 2015 03:42 PM   Total Posts: 72   [ # 7 ]

Please, can someone explain how the above code works??? 

in generic terms what is _pickingCollisionVO,  _pickingCollisionVO.entity and _productModel.productMesh.

I believe _productModel.productMesh is the main object that occludes the hotspot.  Not sure what _pickingCollisionVO &  _pickingCollisionVO.entity is.

Thanks.

 

   

rdoi, Member
Posted: 22 January 2015 10:46 PM   Total Posts: 86   [ # 8 ]

Basically:

- It gets a 3d point projected to the view.
- It then casts a virtual “ray” back to the scene3d, perpendicular to the view plane (camera z axis).
- The ray will intersect some scene elements.
- Get the foremost object that collides.

The same behaviour of mouse events. Check this tutorial on Aways raycasts and picking collider:
http://away3d.com/tutorials/Introduction_to_Mouse_Picking

So the solution for your occluded label point will be:
- Get the 3d point projected to the view
- Pass the coord to a RaycastPicker.
- If the ray collides with an object other than the mesh the point belongs, means that your point is “behind” this object.

var _collidingObject : PickingCollisionVO= PickingType.RAYCAST_FIRST_ENCOUNTERED.getViewCollision( point.x -view.x,  point.y -view.y, view);

_collidingObject.entity wil be the foremost collided object you should compare with your mesh.

Just a side note: Because the above example uses the mouse default picker, all scene elements should be mouseEnabled to be correctly picked.

 

   

drbii, Member
Posted: 24 January 2015 05:37 PM   Total Posts: 72   [ # 9 ]

Ok, I think I understand the theory, but still trying to implement it.  I am getting a “_collidingObject.entity Cannot access a property or method of a null object reference.”

Any ideas?

I am setting my 2d label position to the x and y position of the 3d mesh and then need to evaluate if the 3d Mesh is visible in the view or hidden by other objects.  If visible the label remains on or if the label is behind another object then it needs to hide. 

public static function check_inView():void
   {
   
    
var stage2dPos:Vector3D away3dView_pre.project(_Facet_pre_hotspots.meshes[0].scenePosition);
    
   
    
facet1lText.stage2dPos.x;
    
facet1lText.stage2dPos.y;
    
//facet1lText.z = stage2dPos.z;
    
   
    
if (_Facet_pre_hotspots.meshes[0].worldBounds.isInFrustum(away3dView_pre.camera.frustumPlanesaway3dView_pre.camera.frustumPlanes.length) == true ){
     trace 
("Yes, it is in view");
    
      
facet1lText.alpha 1;
    
      var 
_collidingObject PickingCollisionVOPickingType.RAYCAST_FIRST_ENCOUNTERED.getViewCollisionfacet1lText.,  facet1lText.away3dView_pre);
      
trace (_collidingObject.entity);
    
    
}
    
if (_Facet_pre_hotspots.meshes[0].worldBounds.isInFrustum(away3dView_pre.camera.frustumPlanesaway3dView_pre.camera.frustumPlanes.length) == false ){
     trace 
("No, it is not in view");

     
facet1lText.alpha 0;
    
}
    
    
   } 

Thanks again!

 

 

   

rdoi, Member
Posted: 24 January 2015 06:04 PM   Total Posts: 86   [ # 10 ]
drbii - 24 January 2015 05:37 PM

Ok, I think I understand the theory, but still trying to implement it.  I am getting a “_collidingObject.entity Cannot access a property or method of a null object reference.”
Any ideas?

if “_collidingObject” is null, means the picker did not collided to any object. This happens if it effectly did not collided to anyone or when the collided objects was not “visible” nor “mouseEnabled”, therefore invisible to the picker (because it uses the same picker as the mouse manager). Try mouseEnable all elements on the scene.

drbii - 24 January 2015 05:37 PM

I am setting my 2d label position to the x and y position of the 3d mesh and then need to evaluate if the 3d Mesh is visible in the view or hidden by other objects.  If visible the label remains on or if the label is behind another object then it needs to hide.

This is pretty tricky (as you already realized), the method described will work only for a single point in the view/3d space, not for a polygon or an entire mesh. Not sure if it would be enough.

I could try to make you a sample code to show the concept, if you don’t mind waiting a couple of days.

 

 

   

drbii, Member
Posted: 24 January 2015 06:42 PM   Total Posts: 72   [ # 11 ]

Thanks, rodi, for your quick response!  I will try mouseEnable on all elements.  The null error keeps the scene from even running. The error is thrown before the app even launches. How do I avoid that? 

A sample code would surly be helpful, but I don’t want to take too much of your time.

Much appreciate your help!
Dan

 

   

rdoi, Member
Posted: 29 January 2015 08:28 PM   Total Posts: 86   [ # 12 ]
drbii - 24 January 2015 06:42 PM

Thanks, rodi, for your quick response!  I will try mouseEnable on all elements.  The null error keeps the scene from even running. The error is thrown before the app even launches. How do I avoid that? 

A sample code would surly be helpful, but I don’t want to take too much of your time.

Much appreciate your help!
Dan

Here is the code you can compile and test the raycast concept (full code attached).

The relevant part is the picking test being called on EnterFrame:

private function checkRaycastCollision():void {

   
// This will get the point in the 3d scene (where our target is), and project to the view
   
var point3DInView2D Vector3D view.project(target.scenePosition);

   
// This will raycast a "bean" from the 2d view back to the target.
   
var _collidingObject PickingCollisionVO PickingType.RAYCAST_FIRST_ENCOUNTERED.getViewCollision(point3DInView2D.xpoint3DInView2D.yview);

   
// _collidingObject can be null if collided with nobody.
   // but since we provided a point of an existing mesh, it will collide at least with it.

   // To know if our target is behind (occluded) by some other mesh, just check the collider.
   // The collider will always return the nearer object from the camera
   // if the collider return our target itself, mean nobody is in front of him.

   
if (_collidingObject && _collidingObject.entity == target{
    myLabel
.text="Hi, Im here!";
    
myLabel.xpoint3DInView2D.x;
    
myLabel.ypoint3DInView2D.y;
   
else {
    myLabel
.xmyLabel.y10;
    
myLabel.text="Sorry, I lost the target...";
   
}
  } 

I see you were very close to it, you just missed the view projection part.

Just some remarks as already stated before:
- I used the standard mouse picking collider, so all meshes must be mouseEnabled. You can implement your own optimized picker that doesn’t require it.
- The picking collision is a expensive operation, because it traverses all elements in the scene. Just expect performance issues if abused.

 

 

File Attachments
PickerTest.as  (File Size: 6KB - Downloads: 262)
   
   

X

Away3D Forum

Member Login

Username

Password

Remember_me



X