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.
IndexProgramming Questions & HelpPrograms › Rotating a cube with mouse, works but...
Page Index Toggle Pages: 1
Rotating a cube with mouse, works but... (Read 4635 times)
Rotating a cube with mouse, works but...
May 11th, 2010, 12:10pm
 
Hey,
I'm a new member in this forum, I want to try a few things with Processing. I'm a Java developer mostly dealing with Interactive-devices.

Lets see if there is an easy solution for my question.
I want to rotate a cube with the mouse. This works quite well, but if I rotate for example around the y axis, then around x axis, I want this to happen step by step. Right now I allways rotate around the origin of the cube, not around its new position.


Hmm I hope you understand this...This is a well known issue for me, but maybe there is an easy solution...
Here is my script:


package impl;

import java.util.Vector;

import processing.core.PApplet;

public class RotateCube extends PApplet {

     int cubeXpos;
     int cubeYpos;
     int cubeSize;
     float cubeXrot = 1.0f;
     float cubeYrot = 1.0f;
     int lastPointerX = 0;
     int lastPointerY = 0;
     static int defValLastX = 9999;
     static int threshold = 0;

     
     
     public void setup(){
           
           size(640, 360, P3D);
           background(100);
           lights();
           stroke(255,0,0);

           cubeXpos = width/2;
           cubeYpos = height/2;
           cubeSize = 100;
           
           pushMatrix();
           translate(cubeXpos, cubeYpos, 0);
           rotateY(cubeXrot);
           rotateX(cubeYrot);
           box(100);
           popMatrix();

           line(0, height/2, width, height/2 );
           
           line(width/2, 0, width/2, height );
     }
     
     
     public void draw(){
           
     }
     
     

     public void mouseDragged() {
           

           if(            mouseX > (cubeXpos-(cubeSize/2)) && mouseX <(cubeXpos-(cubeSize/2)) + cubeSize
                       &&      mouseY > (cubeYpos-(cubeSize/2)) && mouseY <(cubeYpos-(cubeSize/2)) + cubeSize){
                 
                 
                 if(lastPointerX != this.defValLastX){
                       
                       /* Checking X Movement */
                       if(lastPointerX > mouseX + threshold){
                             this.cubeXrot = cubeXrot - 0.05f;
                       }
                       else if (lastPointerX < mouseX - threshold){
                             this.cubeXrot = cubeXrot + 0.05f;
                       }
                       
                       
                       /* Checking Y Movement */
                       if(lastPointerY > mouseY + threshold){
                             this.cubeYrot = cubeYrot + 0.05f;
                       }
                       else if (lastPointerY < mouseY - threshold){
                             this.cubeYrot = cubeYrot - 0.05f;
                       }
                       
                       
                       background(100);
                       pushMatrix();
                       translate(cubeXpos, cubeYpos, 0);
                       rotateY(cubeXrot);
                       rotateX(cubeYrot);
                       box(100);
                       popMatrix();
                       
                       
                 }
                 lastPointerX = mouseX;
                 lastPointerY = mouseY;
                 
           }
           
           else{
                 lastPointerX = defValLastX;
                 lastPointerY = defValLastX;
           }
                       
           
     }
     
     
     
}



edit:
There are two other questions that came into my mind:
Is it possible to map a different image on each side of a cube?
Is it possible to develop really large resolutions like four times 1920*1080 as one big desktop (using the span mode) with processing?

Thanks a lot!

Cheers,
Tobi
Re: Rotating a cube with mouse, works but...
Reply #1 - May 11th, 2010, 10:01pm
 
I took a shot at this by having the sketch store the current transformation matrix each time the mouse button is released, and then applying that stored matrix at the start of every subsequent draw.  Unfortunately it still gives a weird rotation effect, and it also makes the cube smaller (!) with each new mouse press.

Here's my version.  Maybe it'll help.

Code:
package impl;

import processing.core.PApplet;
import processing.core.PMatrix3D;

@SuppressWarnings("serial")
public class RotateCube extends PApplet {

int cubeXpos;
int cubeYpos;
int cubeSize;
float cubeXrot = 0.0f;
float cubeYrot = 0.0f;
int lastPointerX = 0;
int lastPointerY = 0;
static int defValLastX = 9999;
static int threshold = 0;

PMatrix3D currentRotMatrix = new PMatrix3D();
PMatrix3D savedRotMatrix = new PMatrix3D();

public void setup(){

size(640, 360, P3D);
background(100);
lights();
stroke(255,0,0);

cubeXpos = width/2;
cubeYpos = height/2;
cubeSize = 100;

pushMatrix();
translate(cubeXpos, cubeYpos, 0);
rotateY(cubeXrot);
rotateX(cubeYrot);
box(100);
popMatrix();

line(0, height/2, width, height/2 );

line(width/2, 0, width/2, height );
}


public void draw(){

}

public void mouseReleased() {
savedRotMatrix.set(currentRotMatrix);
cubeXrot = 0.0f;
cubeYrot = 0.0f;
}

public void mouseDragged() {


if( mouseX > (cubeXpos-(cubeSize/2)) && mouseX <(cubeXpos-(cubeSize/2)) + cubeSize
&& mouseY > (cubeYpos-(cubeSize/2)) && mouseY <(cubeYpos-(cubeSize/2)) + cubeSize){


if(lastPointerX != this.defValLastX){

/* Checking X Movement */
if(lastPointerX > mouseX + threshold){
this.cubeXrot = cubeXrot - 0.05f;
}
else if (lastPointerX < mouseX - threshold){
this.cubeXrot = cubeXrot + 0.05f;
}


/* Checking Y Movement */
if(lastPointerY > mouseY + threshold){
this.cubeYrot = cubeYrot + 0.05f;
}
else if (lastPointerY < mouseY - threshold){
this.cubeYrot = cubeYrot - 0.05f;
}


background(100);
pushMatrix();
translate(cubeXpos, cubeYpos, 0);
applyMatrix(savedRotMatrix);
rotateY(cubeXrot);
rotateX(cubeYrot);
getMatrix(currentRotMatrix);
box(100);
popMatrix();


}
lastPointerX = mouseX;
lastPointerY = mouseY;

}

else{
lastPointerX = defValLastX;
lastPointerY = defValLastX;
}


}



}
Re: Rotating a cube with mouse, works but...
Reply #2 - May 17th, 2010, 4:22am
 
Not too sure what effect you're after.

A month ago I wrote a Scroller class, that would allow someone to move a focus point (around which stuff rotates) through a given 3D space in a smooth fashion. Would that help?
Re: Rotating a cube with mouse, works but...
Reply #3 - May 20th, 2010, 7:00am
 
Hey,
yes this might help.

It is a test program for some sort of interactive game where you have to rotate objects.
I was hoping to find an easy work around or ideas...

Cheers,
Tobi
Re: Rotating a cube with mouse, works but...
Reply #4 - May 20th, 2010, 8:20am
 
check this out, its a new library called proscene:
http://code.google.com/p/proscene/

it has some mousepicking/rotating examples included

http://disi.unal.edu.co/profesores/pierre/MyHome/proscene_examples/MouseGrabber...
Re: Rotating a cube with mouse, works but...
Reply #5 - May 22nd, 2010, 12:52pm
 
That's sweet!

Here's the class I was talking about:

Code:
class Scroller {

float acc = 2;
float damp = .93;

float h_vector = 0;
float v_vector = 0;
float z_vector = 0;

float rh_vector = 0;
float rv_vector = 0;

float z = 200;
float x = 0;
float y = 0;

float rx = 0;
float ry = 0;

Scroller() {

mouseX = width/2;
mouseY = height/2;

}

Scroller(float acc, float damp) {

this.acc = acc;
this.damp = damp;

mouseX = width/2;
mouseY = height/2;

}

Scroller(float x, float y, float z) {

this.x = x;
this.y = y;
this.z = z;

mouseX = width/2;
mouseY = height/2;

}

Scroller(float x, float y, float z, float acc, float damp) {

this.acc = acc;
this.damp = damp;

this.x = x;
this.y = y;
this.z = z;

mouseX = width/2;
mouseY = height/2;

}


void update() {

if(mousePressed) {

rh_vector += (mouseY - pmouseY)/1000.0;
rv_vector += (mouseX - pmouseX)/1000.0; // (add a minus sign in front to inverse motion if that feels more natural)

}

rh_vector *= damp;
rv_vector *= damp;

if(keyPressed) {
if (key == CODED) {
if (keyCode == UP) {
v_vector += acc;
}
if (keyCode == DOWN) {
v_vector -= acc;
}
if (keyCode == LEFT) {
h_vector += acc;
}
if (keyCode == RIGHT) {
h_vector -= acc;
}
}

if(key == '-' || key == '_') {
z_vector += acc;
}
else if(key == '=' || key == '+') {
z_vector -= acc;
}

}
else {
h_vector *= damp;
v_vector *= damp;
z_vector *= damp;
}

x += h_vector;
y += v_vector;
z += z_vector;

rx += rh_vector;
ry += rv_vector;

}

}
Re: Rotating a cube with mouse, works but...
Reply #6 - May 22nd, 2010, 1:19pm
 
In this example (reflecting also in the key mapping of the class pasted above) I misuse the z parameter of scrolling for "zooming". The x and y determine the position on a plane.

Code:
import processing.opengl.*;
import javax.media.opengl.*;

float current_rotation = 0;

float depth = 400;

float rotx;
float roty;

Scroller scroller;

void setup() {
size(700, 700, OPENGL);
frameRate(25);

noStroke();

scroller = new Scroller(0, 0, depth);
}

void draw() {

background(255);
lights();

// Center and spin grid
translate(width/2, height/2, -scroller.z);

roty = scroller.ry - current_rotation%TWO_PI - PI;
rotx = scroller.rx - (current_rotation/3.0)%TWO_PI - PI;

rotateY(roty);
rotateX(rotx);

translate(scroller.x, scroller.y, 0);

fill(255, 0,0);
box(200);

translate(-scroller.x, -scroller.y, 0);

fill(240);
sphere(20);

current_rotation += 0.002;

scroller.update();

}
Re: Rotating a cube with mouse, works but...
Reply #7 - May 24th, 2010, 7:32am
 
I just looked at the PeasyCam library for the first time (even though I've seen it mentioned a billion times on this forum, I'd never checked it out myself before) and it seems to do what you're after.  Even if it isn't exactly what you're looking for, you could probably learn something by browsing its source code.
Re: Rotating a cube with mouse, works but...
Reply #8 - Jun 2nd, 2010, 11:48am
 
Smitty wrote on May 24th, 2010, 7:32am:
I just looked at the PeasyCam library for the first time (even though I've seen it mentioned a billion times on this forum, I'd never checked it out myself before) and it seems to do what you're after.  Even if it isn't exactly what you're looking for, you could probably learn something by browsing its source code.



Thanks for the link! This looks really nice but I think this works only for one cube. I'm thinking about rotating a few cubes of any other object.
Re: Rotating a cube with mouse, works but...
Reply #9 - Jun 2nd, 2010, 2:19pm
 
Rapatsk1 wrote on May 22nd, 2010, 1:19pm:
In this example (reflecting also in the key mapping of the class pasted above) I misuse the z parameter of scrolling for "zooming". The x and y determine the position on a plane.

Code:
import processing.opengl.*;
import javax.media.opengl.*;

float current_rotation = 0;

float depth = 400;

float rotx;
float roty;

Scroller scroller;

void setup() {
 size(700, 700, OPENGL);
 frameRate(25);

 noStroke();

 scroller = new Scroller(0, 0, depth);
}

void draw() {

 background(255);
 lights();

 // Center and spin grid
 translate(width/2, height/2, -scroller.z);

 roty = scroller.ry - current_rotation%TWO_PI - PI;
 rotx = scroller.rx - (current_rotation/3.0)%TWO_PI - PI;

 rotateY(roty);
 rotateX(rotx);

 translate(scroller.x, scroller.y, 0);

 fill(255, 0,0);
 box(200);

 translate(-scroller.x, -scroller.y, 0);

 fill(240);
 sphere(20);

 current_rotation += 0.002;

 scroller.update();

}



Hey,
I had a look at your scene but what is it suposed to do?

Tanks a lot!

Cheers,
Tobi
Re: Rotating a cube with mouse, works but...
Reply #10 - Jun 2nd, 2010, 3:45pm
 
It moves a focus point around in space, around which you can rotate the scene. But after rereading your post, you seem not to want to rotate the whole scene, but only the object. Correct?

Have you tried this proscene library Cedric posted?
Re: Rotating a cube with mouse, works but...
Reply #11 - Jun 3rd, 2010, 6:34am
 
Ah oke, hmm you are right, this not really what I am looking for.

I had a closer look at proscene, the demo I found also works, but I did not find a tutorial or any more detailed explanations.

What I'am trying to figure out is if Pocessing could be a powerful tool to create interactive scenes. In these scenes you should be able to do all the fancy interactive stuff like scaling, rotating, moving, ..., objects (2d or 3d).
The only thing I'am struggeling with right now, is rotating the cube around all axis. I had this problem also with other software but allways found a workaround without calculating matrix etc.

Thanks!

Cheers,
Tobi

Re: Rotating a cube with mouse, works but...
Reply #12 - Jun 3rd, 2010, 7:10am
 
Code:
import processing.opengl.*;
import javax.media.opengl.*;

Cube[] cubes;

void setup() {

size(600, 600, OPENGL);

cubes = new Cube[0];

}

void draw() {

background(0, 255, 200);
lights();
ambientLight(100, 0, 100);

for(int i = 0; i < cubes.length; i++) {
cubes[i].draw();
}

}

void mouseReleased() {
Cube c = new Cube(mouseX, mouseY);
cubes = (Cube[]) append(cubes, c);
}

class Cube {

float x, y;
float rotx, roty;
float rdx, rdy;

Cube(float x, float y) {

this.x = x;
this.y = y;

rotx = random(TWO_PI);
roty = random(TWO_PI);

rdx = random(-0.01, 0.01);
rdy = random(-0.01, 0.01);

}

void draw() {

// update
rotx = (rotx + rdx)%TWO_PI;
roty = (roty + rdy)%TWO_PI;

// draw
pushMatrix();
translate(x, y, 0);
rotateY(roty);
rotateX(rotx);

noStroke();
box(50);

popMatrix();

}

}


If you change the random rotation to rotation based on the dragging of the mouse (or something like that) & apply it to the currently "focused cube" (screenX() etc. or the proscene library), you're done?
Re: Rotating a cube with mouse, works but...
Reply #13 - Jun 3rd, 2010, 12:44pm
 
Yes I'll try this asap.

I have another problem with your source code if I try to run it in Eclipse.

I created two classes:

package TestProscene;
import processing.core.PApplet;


public class Test2 extends PApplet {


     Cube[] cubes;

     public void setup() {
       
       size(600, 600, OPENGL);        
       cubes = new Cube[0];
     }

     public void draw() {
       
       background(0, 255, 200);
       lights();
       ambientLight(100, 0, 100);
       
       for(int i = 0; i < cubes.length; i++) {
         cubes[i].draw();
       }
       
     }

     public void mouseReleased() {
       Cube c = new Cube(mouseX, mouseY);
       cubes = (Cube[]) append(cubes, c);
       
     }
     
}


And:


package TestProscene;

import processing.core.PApplet;

class Cube extends PApplet {
       
       float x, y;
       float rotx, roty;
       float rdx, rdy;
       
       public Cube(float x, float y) {
         
         this.x = x;
         this.y = y;
         
         rotx = random(TWO_PI);
         roty = random(TWO_PI);
         
         rdx = random(-0.01f, 0.01f);
         rdy = random(-0.01f, 0.01f);
         
       }
       
       
       
       public void draw() {
         
         // update
         rotx = (rotx + rdx)%TWO_PI;
         roty = (roty + rdy)%TWO_PI;
         
         // draw
         pushMatrix();
         translate(x, y, 0);
         rotateY(roty);
         rotateX(rotx);
         
         noStroke();
         box(50);
         
         popMatrix();
         
       }
       
     }




If I try to run Test2 class I get the following Exception whan I click into the app:

Exception in thread "Animation Thread" java.lang.NullPointerException
     at processing.core.PApplet.pushMatrix(Unknown Source)
     at TestProscene.Cube.draw(Cube.java:33)
     at TestProscene.Test2.draw(Test2.java:28)
     at processing.core.PApplet.handleDraw(Unknown Source)
     at processing.core.PApplet.run(Unknown Source)
     at java.lang.Thread.run(Unknown Source)



I hope someone can help me with this?


Regards,
Tobi
Re: Rotating a cube with mouse, works but...
Reply #14 - Jun 3rd, 2010, 1:32pm
 
AFAIK, you can't have two PApplet classes in the same program. Beside, Cube isn't a PApplet, it is a standalone class which must be given a PApplet instance to be able to call PApplet functions.
Page Index Toggle Pages: 1