We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProcessing DevelopmentLibraries,  Tool Development › How to over ride calls to things like fill()
Pages: 1 2 
How to over ride calls to things like fill()? (Read 3825 times)
How to over ride calls to things like fill()?
Feb 19th, 2010, 2:32am
 
So I'm writing a picking library.
I have it all set up so I can make libraries. That's working great.

But my library needs to over-ride several standard functions.
Specifically, fill(), stroke(), background(), and lights().

Basically I need to make it so that, when I call theParent.draw() from my library, these functions don't change the fill or stroke color, set the background color, or enable the lights.

While I know I could make the user of my library use:
Picking pick = new Picking(this);
pick.background(0);
pick.stroke(128);
pick.fill(255);
pick.lights();

This looks ugly, and is totally not what I want.
Can I over-ride these functions somehow?
Re: How to over ride calls to things like fill()?
Reply #1 - Feb 19th, 2010, 2:58am
 
i am not sure but cant you use pushStyle() popStyle()  to prevent it from changing anything withing the sketch ?
Re: How to over ride calls to things like fill()?
Reply #2 - Feb 19th, 2010, 3:17am
 
Did you ever play Duckhunt on the NES?
You point this gun at the screen, and when you pull the trigger, the image on the screen changed to black and white - the ducks are white, and the rest of the screen is black. You know you hit a duck if the gun sees a white spot when it looks out the end of the barrel.

This is what I'm trying to do with the picking library.
When you click (shoot) the mouse (gun), the 3D image on the screen (the image) is drawn to an off-screen PGraphics object using different colors (not just black and white) for different objects. Then we look at what color was drawn at the point where the mouse was clicked (out the gun barrel), see what color was there, and then we know what object that was.

The trouble is that the only way to draw the scene to the off-screen PGraphics object is to do what's in draw(), but render it to the different PGraphics object.
This isn't the problem.

The problem is that the calls to things in draw() that would change the colors of what's being draw to the off-screen buffer need to be ignored when rendering to the other PGraphics object. In short, I need a way to intercept the calls to fill(), stroke(), background(), and lights(), and ignore them when drawing to the offscreen PGraphics object. And I want to do this from a library, which is why I ask here.
Re: How to over ride calls to things like fill()?
Reply #3 - Feb 19th, 2010, 3:38am
 
This is the big question indeed : How to build a picking library that doesn't require the user to code two different methods (one for regular screen output, another one for picking buffer) ?

Maybe force them to implement an interface with a dedicated view(boolean screenMode) method and put a conditionnal test before each fill, stroke, lights, etc... statement :

Code:
class MyPickableObject implements Pickable {
 
 void view(boolean screenMode) {
   if (screenMode) fill(#804080);
   rect(20, 20, 20, 20);
 }
 
}


then you just need to call view(false) on each registered object to get the buffer output.
Re: How to over ride calls to things like fill()?
Reply #4 - Feb 19th, 2010, 3:56am
 
For the user, small code changes are better than big code changes.
Especially if those small changes can be done with a replace all...

I'd much rather just do what my tab-of-code version did, but with a library, than force the user to implement classes of pickable things.

That is, at least until someone works out a way to do this properly.
Re: How to over ride calls to things like fill()?
Reply #5 - Feb 19th, 2010, 5:39am
 
Implementing a Pickable interface is not simple, but is way more powerful. Two examples :

#1 > Say you draw a complex shape. Maybe you don't want to do the same complicated shape in the buffer. Maybe you just want to draw a bounding box/sphere that will save you many FPS.

#2 > Say you draw a very tiny shape, so tiny that it's going to be hard to click. Maybe you want to draw a bigger shape in the buffer so that the user can pick it more easily.

But anyway, I am discussing here what I think is the best way to handle 3d picking, which is not really what you asked for, sorry  :-[

Back to your question :

The only proper way I'm thinking of is adding the ability for libraries to be notified when a camera event - camera(), rotate(), translate() and so on... - or a drawing event - line(), stroke(), fill(), ... - occurs (just like they are already notified when a mouse / keyboard event occurs). It would then be easy to redraw the scene in the buffer and you could just decide to ignore the fill() events. That would be terrific!
Re: How to over ride calls to things like fill()?
Reply #6 - Feb 19th, 2010, 5:56am
 
#1: This is a very good point. Shocked I will consider this problem, and possible solutions for it, when I write my library. One possible solution that springs to mind is to give the user the ability to query if the current render being done is for the true scene or the off-screen one. Smiley

#2: This is not a very good point. Tongue The user can simply set the fill to fill(0,0,0,0), and then draw a large enough bounding box around the small clickable. When the trigger gets pulled, the box is suddenly there! Wink

I've been digging in the docs all night. I've looked at functions I didn't even know existed in the hopes of finding something that might be useful (beginRaw(), beginRecord(), and setParent() spring to mind). No luck.
Re: How to over ride calls to things like fill()?
Reply #7 - Feb 19th, 2010, 6:05am
 
Using fill(0, 0, 0, 0) is a bit tricky, but it's a smart trick ;-)

Why not using the same trick for issue #1 ?

Code:
// simple object
startPicking(1);
 fill(#102030);
 box(20);
stopPicking();

// complicated shape
startPicking(2);
 fill(0, 0, 0, 0);
 box(40);
stopPicking();
beginShape();
fill(myColor);
renderMyComplicatedShape();
endShape();
Re: How to over ride calls to things like fill()?
Reply #8 - Feb 19th, 2010, 6:40am
 
TfGuy44 wrote on Feb 19th, 2010, 3:17am:
The problem is that the calls to things in draw() that would change the colors of what's being draw to the off-screen buffer need to be ignored when rendering to the other PGraphics object. In short, I need a way to intercept the calls to fill(), stroke(), background(), and lights(), and ignore them when drawing to the offscreen PGraphics object. And I want to do this from a library, which is why I ask here.

See the PDF library, it has the same problem...
Re: How to over ride calls to things like fill()?
Reply #9 - Feb 19th, 2010, 6:49am
 
Because the code you've posted would render the complex shape for the off-screen buffer too!

You'd have to query it:
if( notPicking ){
 renderComplex();
} else {
 massiveBoundingBox();
}

The more I think about it, the more I feel like my first approach was the correct one. A library for this would be wonderful - if I could get it to just work like magic. Until then, I'm just going to refine the tab-of-code.
Re: How to over ride calls to things like fill()?
Reply #10 - Feb 19th, 2010, 6:50am
 
Quote:
See the PDF library, it has the same problem...

It has the same problem, or the solution to that problem?
Re: How to over ride calls to things like fill()?
Reply #11 - Feb 19th, 2010, 8:40am
 
I think you cannot do better than PDF (unless using some black magic reflection or such bytecode manips... Smiley), since the Processing authors had a similar problem (drawing both on screen and on PDF) and solved it like you can see.
Re: How to over ride calls to things like fill()?
Reply #12 - Feb 20th, 2010, 9:31am
 
I had a look at the source code. There is this recorder (PGraphics) object, where all camera / drawing events are mirrored. Might be the key...
Re: How to over ride calls to things like fill()?
Reply #13 - Feb 20th, 2010, 11:23am
 
Just found the solution!  Cheesy

You need to build a custom renderer (that extends PGraphics) and tell Processing to use it as the recorder. All camera / drawing events will then be mirrored to your renderer. Just override the methods you want to ignore.

In your library :

Code:
public class PickingBuffer extends PGraphics3D {
 public PickingBuffer() {}
 public boolean displayable() {
   return false;
 }
 public fill(int i) {
   PApplet.println("fill() will be ignored");
 }
}


In your PDE :

Code:
import nknk.*;

recorder = createGraphics(100, 100, "nknk.PickingBuffer");
fill(10);
Re: How to over ride calls to things like fill()?
Reply #14 - Feb 20th, 2010, 3:48pm
 
Thanks antiplastik... This is the same solution I came up with, independently, while looking at the DXF library's source code yesterday.  Grin

I would have posted about it, but I've been busy these last few days.

I suppose I'll have to give you some credit in the library now...  Roll Eyes
Pages: 1 2