OpenTK. Trouble with mirror reflection - reflection

I have some problems with rendering of mirror reflection in OpenTK. I need to see reflection of objects only from one side from my mirror, but my program also gives reflection from another side and it hides the first one. Could you help me?
private void glControl1_Load(object sender, EventArgs e)
{
loaded = true;
GL.ClearColor(Color.SkyBlue);
initRendering();
Matrix4 p = Matrix4.CreatePerspectiveFieldOfView((float)(80 * Math.PI / 180), 1, 20, 500);
GL.MatrixMode(MatrixMode.Projection);
GL.LoadMatrix(ref p);
Matrix4 modelview = Matrix4.LookAt(70, 70, 70, 0, 0, 0, 0, 1, 0);
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadMatrix(ref modelview);
}
private void glControl1_Paint(object sender, PaintEventArgs e)
{
if (!loaded)
return;
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
drawScene();
/*axes*/
GL.Color3(Color.Black);
GL.Begin(BeginMode.Lines);
GL.Vertex3(0, 0, 0);
GL.Vertex3(70, 0, 0);
GL.Vertex3(0, 0, 0);
GL.Vertex3(0, 70, 0);
GL.Vertex3(0, 0, 0);
GL.Vertex3(0, 0, 70);
GL.End();
glControl1.SwapBuffers();
}
void initRendering()
{
GL.ShadeModel(ShadingModel.Flat);
GL.ClearDepth(1.0f);
GL.ClearStencil(0);
GL.Enable(EnableCap.DepthTest);
GL.DepthFunc(DepthFunction.Lequal);
GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest);
GL.Enable(EnableCap.AutoNormal);
// Setup the drawing area and shading mode
GL.MatrixMode(MatrixMode.Projection);
GL.LoadIdentity();
GL.Enable(EnableCap.PointSmooth);
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadIdentity();
GL.Enable(EnableCap.Lighting);
GL.LightModel(LightModelParameter.LightModelAmbient, ambientLight);
GL.Enable(EnableCap.Normalize);
GL.Enable(EnableCap.ColorMaterial);
}
public class CustomOpenGLControl : GLControl
{
public CustomOpenGLControl()
: base(new OpenTK.Graphics.GraphicsMode(32, 24, 8))
{
}
}
private void drawFrame()
{
GL.Color3(Color.Red);
GL.Begin(BeginMode.Quads);
GL.Normal3(0.0f, -1.0f, 0.0f);
for (int i = 0; i < upWall.Length; i++)
{
GL.Vertex3(upWall[i].x, upWall[i].y, upWall[i].z);
}
GL.End();
GL.Color3(Color.Yellow);
GL.Begin(BeginMode.Quads);
GL.Normal3(0.0f, -1.0f, 0.0f);
for (int i = 0; i < downWall.Length; i++)
{
GL.Vertex3(downWall[i].x, downWall[i].y, downWall[i].z);
}
GL.End();
GL.Color3(Color.Green);
GL.Begin(BeginMode.Quads);
GL.Normal3(0.0f, 0.0f, -1.0f);
for (int i = 0; i < backWall.Length; i++)
{
GL.Vertex3(backWall[i].x, backWall[i].y, backWall[i].z);
}
GL.End();
GL.Color3(Color.Blue);
GL.Begin(BeginMode.Quads);
GL.Normal3(-1.0f, 0.0f, 0.0f);
for (int i = 0; i < rightWall.Length; i++)
{
GL.Vertex3(rightWall[i].x, rightWall[i].y, rightWall[i].z);
}
GL.End();
GL.Color3(Color.Orange);
GL.Begin(BeginMode.Quads);
GL.Normal3(1.0f, 0.0f, 0.0f);
for (int i = 0; i < leftWall.Length; i++)
{
GL.Vertex3(leftWall[i].x, leftWall[i].y, leftWall[i].z);
}
GL.End();
}
private void drawMirror()
{
GL.PushMatrix();
GL.Begin(BeginMode.Quads);
GL.Normal3(0.0f, -1.0f, 0.0f);
for (int i = 0; i < mirror.Length; i++)
{
GL.Vertex3(mirror[i].x, mirror[i].y, mirror[i].z);
}
GL.End();
GL.PopMatrix();
}
private void drawScene()
{
GL.Clear(ClearBufferMask.AccumBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit | ClearBufferMask.ColorBufferBit);
double[] eqr = { 0f, y0 + height / 6f, 0f, 0.0f };
GL.PushMatrix();
GL.ColorMask(false, false, false, false);
GL.Enable(EnableCap.StencilTest);
GL.StencilFunc(StencilFunction.Always, 1, 1);
GL.StencilOp(StencilOp.Keep, StencilOp.Keep, StencilOp.Replace);
GL.Disable(EnableCap.DepthTest);
drawMirror();
GL.Enable(EnableCap.DepthTest);
GL.ColorMask(true, true, true, true);
GL.StencilFunc(StencilFunction.Equal, 1, 1);
GL.StencilOp(StencilOp.Keep, StencilOp.Keep, StencilOp.Keep);
GL.Enable(EnableCap.ClipPlane0);
GL.ClipPlane(ClipPlaneName.ClipPlane0, eqr);
GL.PushMatrix();
GL.Scale(1, -1, 1);
drawFrame();
GL.PopMatrix();
GL.Disable(EnableCap.ClipPlane0);
GL.Disable(EnableCap.StencilTest);
GL.Enable(EnableCap.Blend);
GL.Disable(EnableCap.Lighting);
GL.Color4(1, 1, 1, 0.3f);
GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
drawMirror();
GL.Enable(EnableCap.Lighting);
GL.Disable(EnableCap.Blend);
drawFrame();
GL.PopMatrix();
}
}

Sorry, I cant help too much with this. I would run your code, but unfortunately I am not at my programming computer right now, and I don't have any experience with opentk.

Related

p5.js how to correctly compute the 3D rotation of a point in respect of the origin

I'm really struggling here and I can't get it right, not even knowing why.
I'm using p5.js in WEBGL mode, I want to compute the position of on point rotated on the 3 axes around the origin in order to follow the translation and the rotation given to object through p5.js, translation and rotatation on X axis, Y axis and Z axis.
The fact is that drawing a sphere in 3d space, withing p5.js, is obtained by translating and rotating, since the sphere is created at the center in the origin, and there is no internal model giving the 3d-coordinates.
After hours of wandering through some math too high for my knowledge, I understood that the rotation over 3-axis is not as simple as I thought, and I ended up using Quaternion.js. But I'm still not able to match the visual position of the sphere in the 3d world with the coordinates I have computed out of the original point on the 2d-plane (150, 0, [0]).
For example, here the sphere is rotated on 3 axis. At the beginning the coordinates are good (if I ignore the fact that Z is negated) but at certain point it gets completely out of sync. The computed position of the sphere seems to be completely unrelated:
It's really hours that I'm trying to solve this issue, with no result, what did I miss?
Here it follows my code:
//font for WEBGL
var robotoFont;
var dotId = 0;
var rotating = true;
var orbits = [];
var dotsData = [];
function preload() {
robotoFont = loadFont('./assets/Roboto-Regular.ttf');
}
function setup() {
createCanvas(windowWidth, windowHeight, WEBGL);
textFont(robotoFont);
background(0);
let orbit1 = new Orbit(0, 0, 0, 0.5, 0.5, 0.5);
orbit1.obj.push(new Dot(0, 0));
orbits.push(orbit1);
// let orbit2 = new Orbit(90, 45, 0);
// orbit2.obj.push(new Dot(0, 0));
// orbits.push(orbit2);
}
function draw() {
angleMode(DEGREES);
background(0);
orbitControl();
let len = 200;
fill('white');
stroke('white');
sphere(2);
stroke('red');
line(0, 0, 0, len, 0, 0);
text('x', len, 0)
stroke('green');
line(0, 0, 0, 0, len, 0);
text('y', 0, len)
push();
rotateX(90);
stroke('yellow');
line(0, 0, 0, 0, len, 0);
text('z', 0, len)
pop();
dotsData = [];
orbits.forEach(o => o.draw());
textSize(14);
push();
for (let i = 0; i < 2; i++) {
let yPos = -(windowHeight / 2) + 15;
for (let i = 0; i < dotsData.length; i++) {
let [id, pos, pos3d] = dotsData[i];
let [x1, y1, z1] = [pos[0].toFixed(0), pos[1].toFixed(0), pos[2].toFixed(0)];
let [x2, y2, z2] = [pos3d.x.toFixed(0), pos3d.y.toFixed(0), pos3d.z.toFixed(0)];
text(`${id}: (${x1}, ${y1}, ${z1}) -> (${x2}, ${y2}, ${z2})`, -windowWidth / 2 + 5, yPos);
yPos += 18;
}
rotateX(-90);
}
pop();
}
function mouseClicked() {
// controls.mousePressed();
}
function keyPressed() {
// controls.keyPressed(keyCode);
if (keyCode === 32) {
rotating = !rotating;
}
}
class Orbit {
constructor(x, y, z, xr, yr, zr) {
this.obj = [];
this.currentRot = [
x ? x : 0,
y ? y : 0,
z ? z : 0
]
this.rot = [
xr ? xr : 0,
yr ? yr : 0,
zr ? zr : 0
]
}
draw() {
push();
if (rotating) {
this.currentRot[0] += this.rot[0];
this.currentRot[1] += this.rot[1];
this.currentRot[2] += this.rot[2];
}
rotateY(this.currentRot[1]);
rotateX(this.currentRot[0]);
rotateZ(this.currentRot[2]);
noFill();
stroke('white');
ellipse(0, 0, 300, 300);
for (let i = 0; i < this.obj.length; i++) {
let o = this.obj[i];
o.draw();
dotsData.push([o.id, o.getPosition(), this.#get3DPos(o)]);
}
pop();
}
#get3DPos(o) {
let [x, y, z] = o.getPosition();
let w = 0;
let rotX = this.currentRot[0] * PI / 180;
let rotY = this.currentRot[1] * PI / 180;
let rotZ = this.currentRot[2] * PI / 180;
let rotation = Quaternion.fromEuler(rotZ, rotX, rotY, 'ZXY').conjugate();
[x, y, z] = rotation.rotateVector([x, y, z]);
return createVector(x, y, z);
}
}
class Dot {
constructor(angle) {
this.id = ++dotId;
this.x = cos(angle) * 150;
this.y = sin(angle) * 150;
}
draw() {
push();
fill('gray');
translate(this.x, this.y);
noStroke();
sphere(15);
pop();
}
getPosition() {
return [this.x, this.y, 0];
}
}
It doesn't work in stackoverflow because I need local asset like the font.
Here the working code: https://editor.p5js.org/cigno5/sketches/_ZVq0kjJL
I've finally sorted out. I can't really understand why works this way but I didn't need quaternion at all, and my first intuition of using matrix multiplications to apply rotation on 3-axis was correct.
What I did miss in first instance (and made my life miserable) is that matrix multiplication is not commutative. This means that applying rotation on x, y and z-axis is not equivalent to apply same rotation angle on z, y and x.
The working solution has been achieved with 3 simple steps:
Replace quaternion with matrix multiplications using vectors (method #resize2)
Rotating the drawing plane with Z-Y-X order
Doing the math of rotation in X-Y-Z order
//font for WEBGL
var robotoFont;
var dotId = 0;
var rotating = true;
var orbits = [];
var dotsData = [];
function preload() {
robotoFont = loadFont('./assets/Roboto-Regular.ttf');
}
function setup() {
createCanvas(windowWidth, windowHeight, WEBGL);
textFont(robotoFont);
background(0);
let orbit1 = new Orbit(0, 0, 0, 0.5, 0.5, 0.5);
orbit1.obj.push(new Dot(0, 0.5));
orbits.push(orbit1);
// let orbit2 = new Orbit(90, 45, 0);
// orbit2.obj.push(new Dot(0, 0));
// orbits.push(orbit2);
}
function draw() {
angleMode(DEGREES);
background(0);
orbitControl();
let len = 200;
fill('white');
stroke('white');
sphere(2);
stroke('red');
line(0, 0, 0, len, 0, 0);
text('x', len, 0)
stroke('green');
line(0, 0, 0, 0, len, 0);
text('y', 0, len)
push();
rotateX(90);
stroke('yellow');
line(0, 0, 0, 0, len, 0);
text('z', 0, len)
pop();
dotsData = [];
orbits.forEach(o => o.draw());
textSize(14);
push();
for (let i = 0; i < 2; i++) {
let yPos = -(windowHeight / 2) + 15;
for (let i = 0; i < dotsData.length; i++) {
let [id, pos, pos3d] = dotsData[i];
let [x1, y1, z1] = [pos[0].toFixed(0), pos[1].toFixed(0), pos[2].toFixed(0)];
let [x2, y2, z2] = [pos3d.x.toFixed(0), pos3d.y.toFixed(0), pos3d.z.toFixed(0)];
text(`${id}: (${x1}, ${y1}, ${z1}) -> (${x2}, ${y2}, ${z2})`, -windowWidth / 2 + 5, yPos);
yPos += 18;
}
rotateX(-90);
}
pop();
}
function mouseClicked() {
// controls.mousePressed();
}
function keyPressed() {
// controls.keyPressed(keyCode);
if (keyCode === 32) {
rotating = !rotating;
}
}
class Orbit {
constructor(x, y, z, xr, yr, zr) {
this.obj = [];
this.currentRot = [
x ? x : 0,
y ? y : 0,
z ? z : 0
]
this.rot = [
xr ? xr : 0,
yr ? yr : 0,
zr ? zr : 0
]
}
draw() {
push();
if (rotating) {
this.currentRot[0] += this.rot[0];
this.currentRot[1] += this.rot[1];
this.currentRot[2] += this.rot[2];
}
rotateZ(this.currentRot[2]);
rotateY(this.currentRot[1]);
rotateX(this.currentRot[0]);
noFill();
stroke('white');
ellipse(0, 0, 300, 300);
for (let i = 0; i < this.obj.length; i++) {
let o = this.obj[i];
o.draw();
dotsData.push([o.id, o.getPosition(), this.#get3DPos(o)]);
}
pop();
}
#get3DPos(o) {
let [x, y, z] = o.getPosition();
let pos = createVector(x, y, z);
pos = this.#rotate2(pos, createVector(1, 0, 0), this.currentRot[0]);
pos = this.#rotate2(pos, createVector(0, 1, 0), this.currentRot[1]);
pos = this.#rotate2(pos, createVector(0, 0, 1), this.currentRot[2]);
return pos;
}
//https://stackoverflow.com/questions/67458592/how-would-i-rotate-a-vector-in-3d-space-p5-js
#rotate2(vect, axis, angle) {
// Make sure our axis is a unit vector
axis = p5.Vector.normalize(axis);
return p5.Vector.add(
p5.Vector.mult(vect, cos(angle)),
p5.Vector.add(
p5.Vector.mult(
p5.Vector.cross(axis, vect),
sin(angle)
),
p5.Vector.mult(
p5.Vector.mult(
axis,
p5.Vector.dot(axis, vect)
),
(1 - cos(angle))
)
)
);
}
}
class Dot {
constructor(angle, speed) {
this.id = ++dotId;
this.angle = angle;
this.speed = speed
}
draw() {
this.angle += this.speed;
this.x = cos(this.angle) * 150;
this.y = sin(this.angle) * 150;
push();
fill('gray');
translate(this.x, this.y);
noStroke();
sphere(15);
pop();
}
getPosition() {
return [this.x, this.y, 0];
}
}
And now it works like a charm:
https://editor.p5js.org/cigno5/sketches/PqB9CEnBp

the function display() does not exist

I keep getting the error "the function display() does not exist. I'm just trying to put my own image in instead of a pre drawn ellipse in processing. Here is my code:
import processing.serial.*;
import cc.arduino.*;
import com.tinkerkit.*;
Arduino arduino;
//declare the button
TKButton but;
TKButton but1;
{
arduino = new Arduino(this, Arduino.list()[2], 57600);
}
PFont myFont;
PImage ball1;
int pScore;
// don't touch em!
int gameState; //0= pre game 1= in game 2= game over
//setting up perimeter to contain ball character
int width = 600;
int height = 600;
void setup() {
size(width, height);
smooth();
//myFont = loadFont("MyFutura.vlw");
//textFont(myFont);
gameState = 0;
ball1 = loadImage("ball.gif");
pScore = 0;
}
{
but = new TKButton(arduino, TK.I0);
but1 = new TKButton(arduino, TK.I1);
}
void draw() {
background(0);
if (gameState==0) {
fill(255, 255, 255, 70);
rect(-10, 30, 370, 70, 7);
fill(255, 255, 255, 70);
rect(-10, 120, 330, 50, 7);
fill(255);
textSize(60);
text("Ball Game", 30, 85);
textSize(40);
text("Press B to Start", 30, 157);
if (keyPressed && key == 'b') {
gameState = 1;
}
}
if (gameState == 2) {
fill(255, 255, 255, 70);
rect(-10, 30, 370, 70, 7);
fill(255, 255, 255, 70);
rect(-10, 120, 250, 50, 7);
fill(255, 255, 255, 70);
rect(-10, 190, 330, 50, 7);
fill(255);
textSize(50);
text("Final Score:", 20, 85);
text(pScore, 280, 85);
textSize(30);
text("Play Again?", 30, 157);
textSize(30);
text("Press R to Restart", 30, 225);
if (keyPressed && key == 'r') {
gameState = 0;
setup();
}
}
ball1.display();
ball1.keyPressed();
}
void display() {
fill(255);
noStroke();
}
void reset() {
...
}
class ball1 {
float x;
float y;
float speed;
float r; //radius
color c = color(255, 20, 245);
ball1(float tempX, float tempY, float tempR) {
x = tempX;
y = tempY;
r = tempR;
speed = 0;
}
void change() {
c = color(random(255), random(220), random(245));
}
void display() {
fill (c);
noStroke();
ellipse(x, y, r, r);
}
//key commands
//ball flies off page in response to key command
void keyPressed() {
if (key == CODED) {
}
if (but.read ()== TK.HIGH) {
x = x+5;
if (x >= width - 25) {
x = width - 25;
}
println(but.read());
} else if (but1.read() == TK.HIGH) {
x = x-5;
if (x <= 25) {
x = 25;
}
println(but1.read());
}
}
}
Your ball1 variable is of type PImage.
The PImage class does not have a display() method.
Maybe your ball1 variable should be inside the ball1 class? If so, rename your class to something sane like Ball (in other words, follow the standard naming conventions and don't use the same name for a class and variable). Then rename your ball1 variable to something sane like ballImage. Then inside your Ball class's display() function, call image(ballImage, x, y) or one of the other image() functions.
Recommended reading:
https://processing.org/reference/PImage.html
https://processing.org/reference/image_.html

Artifacts when using Serial data to trigger sketch

I am writing a small program in Processing to display the values of a speed trap and elapsed time(like a drag strip, but for a waterslide for Australia Day) coming from a microcontroller over serial.
I have had the Processing sketch running and have done most of the development with just a mouse click to imitate new data and run the program, I also have set up the hardware and had it running with the microcontroller sending the serial data and the program displaying it.
I have done some further development, and now when it runs I am getting some strange things happening, boxes sometimes come through in the wrong color, some artifacts in the displayed numbers, and a lot of wrong colors for only some of the graph(the graph is made with a for loop and the color is set outside of it).
I have tried adding in some delays to make sure its getting a full string of data and I have also tried moving around the sub routines but nothing works.
The faults only appeared after I added in the elapsed time code to the serial data, before it was just one string, now it is two numbers separated by a colon.
I have put my code in here as well, its pretty straight forward, I am only new to programming, please excuse(and point out!) any errors.
import processing.serial.*;
Serial myPort;
float inString;
float inFloat0, inFloat1;
float[] list = new float[0];
float[] etlist = new float[0];
PFont f1, f2, f3, f4, f5, f6;
int index;
float rank;
float percentage;
int trapDistance = 1000;
int SgraphH = 38; //Speed graph scale
int ETgraphH = 15; //ET graph scale
int valueX = 0;
int valueY = 0;
boolean graph30 = false, graph690 = false;
color c1, c2, c3 = color(220, 0, 0), c4 = color(220, 0, 0);
int boxX = 295, boxY = 430, boxSize = 15; //Graph 30 box
void setup () {
size(1280, 700);
index = 0;
//Load list from textfile
String loadlist[] = loadStrings("list.txt");
for (int i = 0; i < loadlist.length; i++) {
String[] split = split(loadlist[i], ',');
list = append(list, float(split[0]));
etlist = append(etlist, float(split[1]));
index++;
}
println(Serial.list());
myPort = new Serial(this, Serial.list()[0], 9600);
myPort.bufferUntil('\n');
//Create fonts
f1 = createFont("Arial Unicode MS", 20);
f2 = createFont("Arial Unicode MS", 240);
f3 = createFont("Arial Unicode MS", 35);
f4 = createFont("Arial Unicode MS", 15);
f5 = createFont("Arial Unicode MS", 15);
f6 = createFont("Arial Unicode MS", 12);
}
void draw () {
stroke(225);
fill(225);
rectMode(CORNER);
rect(0, 0, 500, 20);
fill(0);
text(mouseX, 20, 20);
text(mouseY, 50, 20);
text(mouseX - valueX, 80, 20);
text(mouseY - valueY, 110, 20);
}
void mousePressed() {
//Check if Mouse is over button and toggle Graph on
if (mouseX > boxX && mouseX < boxX+boxSize && mouseY >boxY && mouseY < boxY+boxSize) {
if (graph30) {
graph30 = false;
c3 = color(220, 0, 0);
}
else {
graph30 = true;
c3 = color(0, 220, 0);
}
create();
graphCheck();
graph();
}
//Check if Mouse is over button and toggle Graph on
if (mouseX > boxX+100 && mouseX < boxX+100+boxSize && mouseY >boxY && mouseY < boxY+boxSize) {
if (graph690) {
graph690 = false;
c4 = color(220, 0, 0);
}
else {
graph690 = true;
c4 = color(0, 220, 0);
}
create();
graphCheck();
graph();
}
}
void serialEvent (Serial myPort) {
delay(100);
String inString = myPort.readStringUntil('\n');
delay(100);
if (inString != null) {
inString = trim(inString);
String[] split = split(inString, ',');
inFloat0 = float(split[0]);
inFloat1 = float(split[1]);
index++;
float speed = trapDistance / inFloat0 * 3.6;
list = append(list, speed);
float et = inFloat1;
etlist = append(etlist, et);
//Clear screen
background(225);
//Run sub routines
create();
graphCheck();
graph();
}
}
void delay(int delay)
{
int time = millis();
while(millis() - time <= delay);
}
void create() {
//Clear screen
background(225);
//Sorting
float[] sortlist = new float[index+1];
sortlist = sort(list);
float[] sortetlist = new float[index+1];
sortetlist = sort(etlist);
//Calculate rank
int pos = 1;
while (list[index-1] > sortlist[pos - 1]) {
pos++;
}
if (pos == 1) {
rank = 0;
}
else {
rank = (pos / float(sortlist.length));
}
//Calculate Percentage of Speed
percentage = list[index-1] / sortlist[sortlist.length -1];
//Speed colour for fastest and slowest
if (index != 0) {
if (list[index-1] < sortlist[1]) {
c1 = color(240, 0, 0);
}
else if (list[index-1] > sortlist[index-1]) {
c1 = color(0, 240, 0);
}
else {
c1 = color(255);
}
}
else {
c1 = color(255);
}
//ET colour for fastest and slowest
if (index != 0) {
if (etlist[index-1] < sortetlist[1]) {
c2 = color(240, 0, 0);
}
else if (etlist[index-1] > sortetlist[index-1]) {
c2 = color(0, 240, 0);
}
else {
c2 = color(255);
}
}
else {
c2 = color(255);
}
//Boxes
rectMode(CORNER);
stroke(0);
fill(c1);
rect(15, 15, width-30, 200); //Speed
fill(c2);
rect(15, 230, width-30, 200); //ET
fill(255);
rect(15, height - 255, 125, 240); //Left
rect(155, height -255, 125, 240); //Left
rect(width - 140, height - 255, 125, 240); //Right
rect(width - 280, height - 255, 125, 240); //Right
//Text
fill(0);
textFont(f3);
textAlign(CENTER);
text("Speed", 78, height - 220);
text("ET", width - 78, height - 220);
text("ET", 218, height - 220);
text("Speed", width - 218, height - 220);
textFont(f4);
textAlign(LEFT);
text("Trap Distance: " + trapDistance + "mm", 2, height - 2);
//Big Numbers
textAlign(CENTER);
textFont(f2);
text(String.format("%.2f", list[index-1])+"km/h", width/2, 200); //Speed
text(String.format("%.2f", etlist[index-1])+"sec", width/2, 415); //ET
//Last 10
for (int i = 0; i <= index-1 && i < 10; i++) {
textAlign(LEFT);
textFont(f5);
text((index-1 - i + 1)+". "+String.format("%.3f", list[index-1 - i])+"km/h", 23, (height - 200 + (i * 20)));
}
//Last 10 ET
for (int i = 0; i <= index-1 && i < 10; i++) {
textAlign(LEFT);
textFont(f5);
text((index-1 - i + 1)+". "+String.format("%.3f", etlist[index-1 - i])+"sec", 163, (height - 200 + (i * 20)));
}
//Fastest
for (int i = 0; i <= index-1 && i < 10; i++) {
textAlign(CENTER);
textFont(f5);
text((i+1)+". "+String.format("%.3f", sortlist[sortlist.length - (i+1)])+"km/h", width - 220, (height - 200 + (i * 20)));
}
//Fastest ET
for (int i = 0; i <= index-1 && i < 10; i++) {
textAlign(CENTER);
textFont(f5);
text((i+1)+". "+String.format("%.3f", sortetlist[i])+"sec", width - 80, (height - 200 + (i * 20)));
}
//Create string for saving to text file
String[] listString = new String[index-1+1];
for (int i = 0; i < index-1+1; i++) {
listString[i] = (Float.toString(list[i]) + ',' + Float.toString(etlist[i]));
}
//Save to text file
saveStrings("list.txt", listString);
//Graph with curves
// beginShape();
// stroke(125, 125, 255);
// for (int i = 1; i <= index && i < 34; i++) {
// float y = map(list[index - (i - 1)], 0, SgraphH, 150, 0);
// curveVertex((width + 25 - (i * 25)), 25 + y);
// }
// endShape();
}
void graph() {
//Create graph area
fill(255);
rectMode(CENTER);
rect(width/2, height - 135, 690, 240);
stroke(192);
for (int i = 1; i < 30.; i++) {
line((((width - 690)/2) + (i * (690/30))), 446, ((((width - 690)/2) + (i * (690/30)))), 684);
}
for (int i = 1; i < 10; i++) {
line(((width - 690)/2)+1, (445 + (i * 24)), (width - (width - 690)/2)-1, (445 + (i * 24)));
}
//Graph last 690
if (graph690) {
stroke(0, 170, 0);
for (int i = 1; i <= index-1 && i < 690; i++) {
float start = map(list[index-1 - (i - 1)], 0, SgraphH, 240, 0);
float end = map(list[index-1 - i], 0, SgraphH, 240, 0);
line(((width - (width - 690)/2) + 1 - (i)), 445 + start, ((width- (width - 690)/2) + 1 - ((i + 1))), 445 + end);
}
}
//Graph last 690
if (graph690) {
stroke(120, 0, 120);
for (int i = 1; i <= index-1 && i < 690; i++) {
float start = map(etlist[index-1 - (i - 1)], 0, ETgraphH, 240, 0);
float end = map(etlist[index-1 - i], 0, ETgraphH, 240, 0);
line(((width - (width - 690)/2) + 1 - (i)), 445 + start, ((width- (width - 690)/2) + 1 - ((i + 1))), 445 + end);
}
}
//Graph last 30 speeds
if (graph30) {
stroke(0, 0, 240);
for (int i = 1; i <= index-1 && i < 31; i++) {
float start = map(list[index-1 - (i - 1)], 0, SgraphH, 240, 0);
float end = map(list[index-1 - i], 0, SgraphH, 240, 0);
line(((width - (width - 690)/2) + 23 - (i * 23)), 445 + start, ((width- (width - 690)/2) + 23 - ((i + 1) * 23)), 445 + end);
}
}
//Graph last 30 ETs
if (graph30) {
stroke(240, 0, 0);
for (int i = 1; i <= index-1 && i < 31; i++) {
float start = map(etlist[index-1 - (i - 1)], 0, ETgraphH, 240, 0);
float end = map(etlist[index-1 - i], 0, ETgraphH, 240, 0);
line(((width - (width - 690)/2) + 23 - (i * 23)), 445 + start, ((width- (width - 690)/2) + 23 - ((i + 1) * 23)), 445 + end);
}
}
fill(0);
textAlign(LEFT);
text("0", width / 2 - 345, height - 15);
text(SgraphH, width / 2 - 345, height - 243);
}
void graphCheck() {
//Draw box and text for graph selection
rectMode(CORNER);
textFont(f6);
textAlign(LEFT);
stroke(0);
fill(0);
text("Graph last 30", boxX+20, boxY+13);
fill(c3);
rect(boxX, boxY, boxSize, boxSize);
stroke(0);
fill(0);
text("Graph last 690", boxX+120, boxY+13);
fill(c4);
rect(boxX+100, boxY, boxSize, boxSize);
}
void keyPressed() {
valueX = mouseX;
valueY = mouseY;
}
Also, when triggered from a mouse click (turning on the graph's) it works fine.
Cheers,
Matt
I fixed it.
When the subroutines were being called by the serial trigger, it some how still allowed the looped code in the draw() function to still run, which was causing the issues.
I just put noLoop() and loop() in before and after the calls for the subroutines.
All good now.

Cannot find class type name "Normalized"- Processing

I'm having a dilemma with this code and have no clue what to do. I'm pretty new to processing. This is a project from this link...
http://blog.makezine.com/2012/08/10/build-a-touchless-3d-tracking-interface-with-everyday-materials/
any help is massively appreciated... Thanks in advance
import processing.serial.*;
import processing.opengl.*;
Serial serial;
int serialPort = 1;
int sen = 3; // sensors
int div = 3; // board sub divisions
Normalize n[] = new Normalize[sen];
MomentumAverage cama[] = new MomentumAverage[sen];
MomentumAverage axyz[] = new MomentumAverage[sen];
float[] nxyz = new float[sen];
int[] ixyz = new int[sen];
float w = 256; // board size
boolean[] flip = {
false, true, false};
int player = 0;
boolean moves[][][][];
PFont font;
void setup() {
size(800, 600, P3D);
frameRate(25);
font = loadFont("TrebuchetMS-Italic-20.vlw");
textFont(font);
textMode(SCREEN);
println(Serial.list());
serial = new Serial(this, Serial.list()[serialPort], 115200);
for(int i = 0; i < sen; i++) {
n[i] = new Normalize();
cama[i] = new MomentumAverage(.01);
axyz[i] = new MomentumAverage(.15);
}
reset();
}
void draw() {
updateSerial();
drawBoard();
}
void updateSerial() {
String cur = serial.readStringUntil('\n');
if(cur != null) {
String[] parts = split(cur, " ");
if(parts.length == sensors) {
float[] xyz = new float[sen];
for(int i = 0; i < sen; i++)
xyz[i] = float(parts[i]);
if(mousePressed && mouseButton == LEFT)
for(int i = 0; i < sen; i++)
n[i].note(xyz[i]);
nxyz = new float[sen];
for(int i = 0; i < sen; i++) {
float raw = n[i].choose(xyz[i]);
nxyz[i] = flip[i] ? 1 - raw : raw;
cama[i].note(nxyz[i]);
axyz[i].note(nxyz[i]);
ixyz[i] = getPosition(axyz[i].avg);
}
}
}
}
float cutoff = .2;
int getPosition(float x) {
if(div == 3) {
if(x < cutoff)
return 0;
if(x < 1 - cutoff)
return 1;
else
return 2;
}
else {
return x == 1 ? div - 1 : (int) x * div;
}
}
void drawBoard() {
background(255);
float h = w / 2;
camera(
h + (cama[0].avg - cama[2].avg) * h,
h + (cama[1].avg - 1) * height / 2,
w * 2,
h, h, h,
0, 1, 0);
pushMatrix();
noStroke();
fill(0, 40);
translate(w/2, w/2, w/2);
rotateY(-HALF_PI/2);
box(w);
popMatrix();
float sw = w / div;
translate(h, sw / 2, 0);
rotateY(-HALF_PI/2);
pushMatrix();
float sd = sw * (div - 1);
translate(
axyz[0].avg * sd,
axyz[1].avg * sd,
axyz[2].avg * sd);
fill(255, 160, 0);
noStroke();
sphere(18);
popMatrix();
for(int z = 0; z < div; z++) {
for(int y = 0; y < div; y++) {
for(int x = 0; x < div; x++) {
pushMatrix();
translate(x * sw, y * sw, z * sw);
noStroke();
if(moves[0][x][y][z])
fill(255, 0, 0, 200);
else if(moves[1][x][y][z])
fill(0, 0, 255, 200);
else if(
x == ixyz[0] &&
y == ixyz[1] &&
z == ixyz[2])
if(player == 0)
fill(255, 0, 0, 200);
else
fill(0, 0, 255, 200);
else
fill(0, 100);
box(sw / 3);
popMatrix();
}
}
}
fill(0);
if(mousePressed && mouseButton == LEFT)
msg("defining boundaries");
}
void keyPressed() {
if(key == TAB) {
moves[player][ixyz[0]][ixyz[1]][ixyz[2]] = true;
player = player == 0 ? 1 : 0;
}
}
void mousePressed() {
if(mouseButton == RIGHT)
reset();
}
void reset() {
moves = new boolean[2][div][div][div];
for(int i = 0; i < sen; i++) {
n[i].reset();
cama[i].reset();
axyz[i].reset();
}
}
void msg(String msg) {
text(msg, 10, height - 10);
}
You are missing a class, in fact, more than one. Go back to the github and download, or copy and paste, all three codes, placing each one in a new tab named same name of the class (well this is not required, but is a good practice). The TicTacToe3D.pde is the main code. To make a new tab choose "new tab" from the arrow menu in Processing IDE (just below the standard button at the right). The code should run. WIll need an Arduino though to really get it working.

JOGL ArcBall not working

I'm trying to embed an existing implementation of ArcBall in JOGL into my own project. It compiles and runs but I doesn't work! I can't play around with the view.
I took the implementation (two classes) from here:
http://www.mdimension.com/page/Software?appNum=1
And followed the instructions of embeding the thing into my own project. Here's the class I'm using ArcBall in:
public class GLRenderer implements GLEventListener {
private static final int MAP_SIZE = 1024;
private static final int STEP_SIZE = 16;
private static final float HEIGHT_RATIO = 1.5f;
private float[][] temperatureMap = new float[MAP_SIZE][MAP_SIZE];
private float scaleValue = 0.15f;
private GLU glu = new GLU();
private ArcBall arcBall = new ArcBall();
public void init(GLAutoDrawable drawable) {
GL gl = drawable.getGL();
gl.glShadeModel(GL.GL_SMOOTH);
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
gl.glClearDepth(1.0f);
gl.glEnable(GL.GL_DEPTH_TEST);
gl.glDepthFunc(GL.GL_LEQUAL);
gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
loadValuesToMap();
arcBall.registerDrawable(drawable);
}
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
GL gl = drawable.getGL();
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL.GL_PROJECTION); // Select The Projection Matrix
gl.glLoadIdentity();
glu.gluPerspective(30,(float)width/(float)height,1.0f,650.0);
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glLoadIdentity();
arcBall.reshape(width, height);
}
public void display(GLAutoDrawable drawable) {
arcBall.displayUpdateRotations();
GL gl = drawable.getGL();
gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
gl.glClear(GL.GL_COLOR_BUFFER_BIT);
gl.glClear(GL.GL_DEPTH_BUFFER_BIT); //added
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
setLight(gl);
positionCamera(glu, gl);
drawXYZ(gl);
arcBall.displayTransform(gl);
drawMap(glu, gl);
gl.glFlush();
}
public void setVertexColor(GL gl, int x, int y) {
float fColor = -0.15f + (temperatureMap[x][y] / 256.0f);
gl.glColor3f(0.0f, 0.0f, fColor);
}
public void drawMap(GLU glu, GL gl) {
int x, z;
float y;
gl.glBegin(GL.GL_QUADS);
for(int X = 0; X <(MAP_SIZE - STEP_SIZE); X += STEP_SIZE) {
for(int Y = 0; Y < (MAP_SIZE -STEP_SIZE); Y += STEP_SIZE) {
// Get The (X, Y, Z) Value For The Bottom Left Vertex
x = X;
y = temperatureMap[X][Y];
z = Y;
// Set The Color Value Of The Current Vertex
setVertexColor(gl, x, z);
gl.glVertex3f(x, y, z);
// Get The (X, Y, Z) Value For The Top Left Vertex
x = X;
y = temperatureMap[X][Y + STEP_SIZE];
z = Y + STEP_SIZE ;
// Set The Color Value Of The Current Vertex
setVertexColor(gl, x, z);
gl.glVertex3f(x, y, z); // Send This Vertex To OpenGL To Be Rendered
// Get The (X, Y, Z) Value For The Top Right Vertex
x = X + STEP_SIZE;
y = temperatureMap[X + STEP_SIZE][Y + STEP_SIZE];
z = Y + STEP_SIZE ;
// Set The Color Value Of The Current Vertex
setVertexColor(gl, x, z);
gl.glVertex3f(x, y, z); // Send This Vertex To OpenGL To Be Rendered
// Get The (X, Y, Z) Value For The Bottom Right Vertex
x = X + STEP_SIZE;
y = temperatureMap[X + STEP_SIZE][Y];
z = Y;
// Set The Color Value Of The Current Vertex
setVertexColor(gl, x, z);
gl.glVertex3f(x, y, z); // Send This Vertex To OpenGL To Be Rendered
}
}
gl.glEnd();
gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
gl.glTranslated(0.1, 0.1, -0.5);
gl.glColor3f(0.0f, 0.0f, 1.0f);
glu.gluSphere(glu.gluNewQuadric(), 0.05f, 32, 32);
gl.glTranslated(0.1, 0.1, -0.1);
gl.glColor3f(0.0f, 1.0f, 0.0f);
glu.gluSphere(glu.gluNewQuadric(), 0.05f, 32, 32);
gl.glTranslated(0.1, -0.1, 0.1);
gl.glColor3f(1.0f, 0.0f, 0.0f);
glu.gluSphere(glu.gluNewQuadric(), 0.05f, 32, 32);
}
public void positionCamera(GLU glu, GL gl) {
glu.gluPerspective(75.0f,1.09,0.1f,500.0f);
glu.gluLookAt(194, 80, 194,
131, 55, 131,
0, 1, 0);
gl.glScalef(scaleValue, scaleValue * HEIGHT_RATIO, scaleValue);
}
public void setLight(GL gl) {
// Prepare light parameters.
float SHINE_ALL_DIRECTIONS = 1;
float[] lightPos = {0, -30, 0, SHINE_ALL_DIRECTIONS};
float[] lightColorAmbient = {0.5f, 0.5f, 0.5f, 0.5f};
float[] diffuseLight = { 0.8f, 0.8f, 0.8f, 1.0f };
float[] lightColorSpecular = {0.5f, 0.5f, 0.5f, 0.5f};
// Set light parameters.
gl.glLightfv(GL.GL_LIGHT1, GL.GL_POSITION, lightPos, 1);
gl.glLightfv(GL.GL_LIGHT1, GL.GL_AMBIENT, lightColorAmbient, 0);
gl.glLightfv(GL.GL_LIGHT1, GL.GL_DIFFUSE, diffuseLight, 0);
gl.glLightfv(GL.GL_LIGHT1, GL.GL_SPECULAR, lightColorSpecular, 0);
// Enable lighting in GL.
gl.glEnable(GL.GL_LIGHT1);
gl.glEnable(GL.GL_LIGHTING);
// Set material properties.
gl.glEnable(GL.GL_COLOR_MATERIAL);
}
public void drawXYZ(GL gl) {
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glBegin(GL.GL_LINES);
gl.glColor3d(1.0, 0.0, 0.0); //red (x)
gl.glVertex3d(-0.1, 0.0, 0.0);
gl.glVertex3d(1500.0, 0.0, 0.0);
gl.glColor3d(0.0, 1.0, 0.0); //green (y)
gl.glVertex3d(0.0, -0.1, 0.0);
gl.glVertex3d(0.0, 1500.0, 0.0);
gl.glColor3d(0.0, 0.0, 1.0); //blue (z)
gl.glVertex3d(0.0, 0.0, 0.1);
gl.glVertex3d(0.0, 0.0, 1500.0);
gl.glEnd();
}
public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
init(drawable);
}
private void loadValuesToMap() {
for(int i = 0; i < MAP_SIZE; i++) {
for(int j = 0; j< MAP_SIZE; j++) {
if(i > 300 && i < 700 && j > 300 && j < 700)
temperatureMap[i][j] = 150;
else
temperatureMap[i][j] = 100;
}
}
}
}
I'm new to openGL soke it might be a stupid mistake. I'd appreciate any help though.
Thanks
The source code is not complete. Where is your frame (AWT Frame or Swing JFrame)? Please look at the example of JOGL on Wikipedia.

Resources