possible bug in getOverlappingObjects() ?
krumza

In my case i have this:

I need to highlight lines when hovering the animated scissors

Dots and lines on 5th layer and scissors on 4th layer.

Lines are stretched sprite 5*5 pixels centered in the geometrical middle between the points that it connects + text sprite with it name

And the scissors are on a different layer and have the animation.

In General scissors were for convenience because the lines are very thin and need something to help you get on them with the mouse cursor So I decided to add functionality with the advent of the scissors as the enlarged area However, you have any difficulty, since just getSpritesInArea(area,layerId,sorted) or getSpritesInScreenArea(area) would not be suitable. They work well with layers but alas, choose only the bounding box

Therefore, I decided to try getOverlappingObjects(), since there is a parameter "oriented" and "pixel". However, immediately revealed embarrassing - getOverlappingObjects() is very sensitive to changes in camera zoom works only under the condition when the camera.z == 1

and if i do something like: 

line.onUpdate = function(){
    this.owner.getSprite(0).setDrawFunction(wade.drawFunctions.boundingBox_());

    var tr = this.owner.overlapsObject(wade.getSceneObject("scissors"),'pixel');
    if(tr){
     console.log("scissors hover me!")
    }
}

it call an error:

wade.js:297 Uncaught TypeError: Cannot read property 'undefined' of undefined
    at TextSprite.Sprite.overlapsSprite (wade.js:297)
    at SceneObject.overlapsSprite (wade.js:247)
    at SceneObject.overlapsObject (wade.js:247)
    at LineBehavior.onUpdate (eval at success (wade.js:32), <anonymous>:203:30)
    at SceneObject.process (wade.js:235)
    at SceneObject.processEvent (wade.js:234)
    at SceneManager.processEvent (wade.js:213)
    at SceneManager.step (wade.js:208)
    at Wade.event_mainLoop (wade.js:458)
    at wade.js:457

Because have textsprite in line object. But but it is not written anywhere.

Ok.eliminate the cause of the text sprite:

var tr = this.owner.getSprite(0).overlapsSprite(wade.getSceneObject("scissors").getSprite(),'pixel');
        	if(tr){
        		console.log("scissors on me!")
}

It work, but slowly as hell - it would be logical to move a process with many lines (which in the present drawing can be up to 50) on a single scissors

But the same code on scissors cal an error:

scissor_cursor.onUpdate = function(){
   if(wade.app.secondary_action=='cut'){
      var tr = false;
      for(var i=0;i<wade.app.LINES.length;i++){
	      tr = sciscursor.overlapsObject(wade.app.LINES[i], 'pixel');
	      if(tr) return;
      }
      if(tr){
		  console.log("something under me")
	}
	} 
}

Error:

wade.js:297 Uncaught TypeError: a.getCurrentAnimation is not a function
    at Sprite.overlapsSprite (wade.js:297)
    at SceneObject.overlapsSprite (wade.js:247)
    at SceneObject.overlapsObject (wade.js:247)
    at SceneObject.sciscursor.onUpdate (eval at success (wade.js:32), <anonymous>:1922:38)
    at SceneObject.process (wade.js:235)
    at SceneObject.processEvent (wade.js:234)
    at SceneManager.processEvent (wade.js:213)
    at SceneManager.step (wade.js:208)
    at Wade.event_mainLoop (wade.js:458)
    at wade.js:457

In the end, I have this code but it only works accurately when camera position.z===1, otherwise increasing the spread

            sciscursor.onUpdate = function(){
            	if(wade.app.secaction=='cut'){
            		var arr = sciscursor.getOverlappingObjects(true,'oriented');
            		if(arr.length>0){
            			var searchlines = search(arr, true, 'line');
						if(searchlines){
							if(Object.keys(wade.app.selectedline).length!==0&&wade.app.selectedline!==searchlines){
				            		wade.app.selectedline.getSprite(0).setImageFile('greenmarker.png',false);
									wade.app.selectedline = searchlines;
									wade.app.selectedline.getSprite(0).setImageFile('images/skyblue.png',false);
							} else {
								wade.app.selectedline = searchlines;
								wade.app.selectedline.getSprite(0).setImageFile('images/skyblue.png',false);
							}
						} else {
							if(Object.keys(wade.app.selectedline).length!==0){
				            		wade.app.selectedline.getSprite(0).setImageFile('greenmarker.png',false);
									wade.app.selectedline = {};
							}						
						}
            		}
		        } 
            };

What to do if the use of 'pixel' causes an error on the animated object and the 'oriented' does not take into account the zoom factor?

1 Comment
Gio

I think you definitely want to use oriented for this, not pixel. Given the size of your images, pixel is always going to be slow.

Saying that, pixel should probably work with text sprites. Slowly, but it should. That's probably a bug, and I will look into it now.

I think that oriented works with different zoom levels normally. However, looking at the code, I think we are not considering the case where you are checking for overlaps between objects that are on different layers, AND those layers have different scale and translate factors, AND you move the camera or change the zoom level.

The quickest fix for now would be to set the scissors layer to have the same scale and translate factors of the lines layer. Alternatively, I think you could fix it by editing sprite.js in the wade source (until we release the next version that will include this fix). Around line 1230, find this code

if (sprite.getRotation())
{
	if (wade[functionPrefix + 'IntersectsOrientedBox'](testObject, sprite.orientedBoundingBox))
	{
		overlappingSprites.push(sprite);
	}
}
else
{
	if (wade[functionPrefix + 'IntersectsBox'](testObject, sprite.boundingBox))
	{
		overlappingSprites.push(sprite);
	}
}

and replace it with this:

var otherRotation = sprite.getRotation();
var otherBoundingBox = otherRotation? sprite.orientedBoundingBox : sprite.boundingBox;
var testFunction = otherRotation? wade[functionPrefix + 'IntersectsOrientedBox'] : wade[functionPrefix + 'IntersectsBox'];
if (this._layer.id != sprite.getLayerId())
{
	otherBoundingBox = wade.screenBoxToWorld(this._layer.id, wade.worldBoxToScreen(sprite.getLayerId(), otherBoundingBox));
}
if (testFunction(testObject, otherBoundingBox))
{
	overlappingSprites.push(sprite);
}

If you edit sprite.js, you don't need to rebuild wade.js (unless you want to). It should be enough to just include sprite.js after wade.js in your index.html

Post a reply
Add Attachment
Submit Reply
Login to Reply