Skip to content

Commit

Permalink
added setIgnoreList and onlyMouseEnabled to IPicker
Browse files Browse the repository at this point in the history
Updated comment for ray origin check when entity has bounds collision
  • Loading branch information
rob-bateman committed Jan 25, 2013
1 parent f7d8393 commit 68a890e
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 10 deletions.
6 changes: 6 additions & 0 deletions src/away3d/core/pick/IPicker.as
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,11 @@ package away3d.core.pick
* @param scene The scene on which the picking object acts.
*/
function getSceneCollision(position:Vector3D, direction:Vector3D, scene:Scene3D):PickingCollisionVO;

/**
* Determines whether the picker takes account of the mouseEnabled properties of entities. Defaults to true.
*/
function get onlyMouseEnabled():Boolean;
function set onlyMouseEnabled(value:Boolean):void;
}
}
65 changes: 56 additions & 9 deletions src/away3d/core/pick/RaycastPicker.as
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,26 @@ package away3d.core.pick

private var _findClosestCollision:Boolean;
private var _raycastCollector:RaycastCollector = new RaycastCollector();
private var _ignoredEntities:Array = new Array();
private var _onlyMouseEnabled:Boolean = true;

protected var _entities:Vector.<Entity>;
protected var _numEntities:uint;
protected var _hasCollisions:Boolean;


/**
* @inheritDoc
*/
public function get onlyMouseEnabled():Boolean
{
return _onlyMouseEnabled;
}

public function set onlyMouseEnabled(value:Boolean):void
{
_onlyMouseEnabled = value;
}

/**
* Creates a new <code>RaycastPicker</code> object.
*
Expand Down Expand Up @@ -64,9 +79,14 @@ package away3d.core.pick
while (node) {
entity = node.entity;

if (isIgnored(entity)) {
node = node.next;
continue;
}

// If collision detected, store in new data set.
if( entity.isVisible && entity._ancestorsAllowMouseEnabled && entity.mouseEnabled && entity.isIntersectingRay(rayPosition, rayDirection ))
_entities[_numEntities++] = entity;
if( entity.isVisible && entity.isIntersectingRay(rayPosition, rayDirection ))
_entities[_numEntities++] = entity;

node = node.next;
}
Expand All @@ -83,11 +103,14 @@ package away3d.core.pick
*/
public function getSceneCollision(position:Vector3D, direction:Vector3D, scene:Scene3D):PickingCollisionVO
{
//clear collector
_raycastCollector.clear();

//setup ray vectors
_raycastCollector.rayPosition = position;
_raycastCollector.rayDirection = direction;

// collect stuff to test
// collect entities to test
scene.traversePartitions(_raycastCollector);

_numEntities = 0;
Expand All @@ -96,6 +119,11 @@ package away3d.core.pick
while (node) {
entity = node.entity;

if (isIgnored(entity)) {
node = node.next;
continue;
}

_entities[_numEntities++] = entity;

node = node.next;
Expand All @@ -107,7 +135,25 @@ package away3d.core.pick

return getPickingCollisionVO();
}


public function setIgnoreList(entities:Array):void
{
_ignoredEntities = entities;
}

private function isIgnored(entity:Entity):Boolean
{
if (_onlyMouseEnabled && (!entity._ancestorsAllowMouseEnabled ||!entity.mouseEnabled))
return true;

var ignoredEntity:Entity;
for each (ignoredEntity in _ignoredEntities)
if (ignoredEntity == entity)
return true;

return false;
}

private function sortOnNearT( entity1:Entity, entity2:Entity ):Number
{
return entity1.pickingCollisionVO.rayEntryDistance > entity2.pickingCollisionVO.rayEntryDistance ? 1 : -1;
Expand Down Expand Up @@ -147,10 +193,11 @@ package away3d.core.pick
}
}
else if (bestCollisionVO == null || pickingCollisionVO.rayEntryDistance < bestCollisionVO.rayEntryDistance) { // A bounds collision with no triangle collider stops all checks.
// Note: rayEntryDistances of 0 mean a collision caused by the ray starting inside the bounds.
// This makes the object eligible for triangle picking but should not represent a successful pick
// if the object's picker is bounds only.
if( pickingCollisionVO.rayEntryDistance != 0 ) {
// Note: a bounds collision with a ray origin inside its bounds is ONLY ever used
// to enable the detection of a corresponsding triangle collision.
// Therefore, bounds collisions with a ray origin inside its bounds can be ignored
// if it has been established that there is NO triangle collider to test
if( !pickingCollisionVO.rayOriginIsInsideBounds ) {
updateLocalPosition( pickingCollisionVO );
return pickingCollisionVO;
}
Expand Down
16 changes: 15 additions & 1 deletion src/away3d/core/pick/ShaderPicker.as
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ package away3d.core.pick
{
private var _stage3DProxy:Stage3DProxy;
private var _context:Context3D;
private var _onlyMouseEnabled:Boolean = true;

private var _objectProgram3D : Program3D;
private var _triangleProgram3D : Program3D;
Expand All @@ -57,6 +58,19 @@ package away3d.core.pick
private var _potentialFound : Boolean;
private static const MOUSE_SCISSOR_RECT : Rectangle = new Rectangle(0, 0, 1, 1);

/**
* @inheritDoc
*/
public function get onlyMouseEnabled():Boolean
{
return _onlyMouseEnabled;
}

public function set onlyMouseEnabled(value:Boolean):void
{
_onlyMouseEnabled = value;
}

/**
* Creates a new <code>ShaderPicker</code> object.
*/
Expand Down Expand Up @@ -167,7 +181,7 @@ package away3d.core.pick
renderable = item.renderable;

// it's possible that the renderable was already removed from the scene
if (!renderable.sourceEntity.scene || !renderable.mouseEnabled) {
if (!renderable.sourceEntity.scene || (!renderable.mouseEnabled && _onlyMouseEnabled)) {
item = item.next;
continue;
}
Expand Down

0 comments on commit 68a890e

Please sign in to comment.