Hi,
I found to make it work and adapted the code of Johnny Lee. But I'm still having some problems with the rigth scaling.
The tunnel is more or less floating in front of me, but doesn't seem to make a fixed box impression.
The problem lies within the right parameters for the frustum() method I think. I would be very glad about some help. ;-)
Here's the code (you can adjust the movment faktor by the mouse position)
- import processing.opengl.*;
import SimpleOpenNI.*;
//movementscaling
float faktor =1;
//the heigth of the visible boxpicture on your screen (=screenheigth in fullscreen mode)
float screenmm=270;
boolean cameraAboveScreen=false;
SimpleOpenNI context;
float fx=0, fz=1, fy=0;
void setup() {
context = new SimpleOpenNI(this);
// enable skeleton generation for all joints
context.enableUser(SimpleOpenNI.SKEL_PROFILE_ALL);
size(1080, 768, OPENGL);
frameRate(30);
background(0);
}
void draw() {
background(0);
//set camera positon according to the persons head postion fx,fy,fz
camera(fx, fy, fz,
fx, fy, 0,
0, 1, 0);
float near = 0.5;
//calculate the frustum parameters according to the persons head postion
float left, right, top, bottom;
left = near*(-.5f * width/height + fx)/fz;
right = near*(.5f * width/height + fx)/fz;
top = near*(-.5f - fy)/fz;
bottom = near*(.5f - fy)/fz;
println(left+" "+right+" "+top+" "+bottom+" fz: "+fz +" faktor "+faktor);
frustum(left, right, top, bottom, near, 100);
// update the cam
context.update();
// calc the skeleton if it's available
int[] userList = context.getUsers();
for (int i=0;i<userList.length;i++)
{
if (context.isTrackingSkeleton(userList[i]))
calcData(userList[i]);
}
drawTunnel();
}
void calcData(int i) {
PVector jointPos = new PVector();
context.getJointPositionSkeleton(i, SimpleOpenNI.SKEL_HEAD, jointPos);
// adjust the movment scaling faktor by Mouse
faktor= map(mouseX, 0, width, 1/10, 1);
//calculate distances in sizes of screenheigth units
float rx= faktor*jointPos.x /screenmm ;
float ry=0;
if (cameraAboveScreen)
ry= faktor*(jointPos.y + (screenmm/2))/screenmm ;
if (!cameraAboveScreen)
ry= faktor*(jointPos.y - (screenmm/2))/screenmm ;
float headDist = faktor*jointPos.z/screenmm ;
//originally fx=-rx and fy=-ry, but this changes the movment dircetion of he perspective
fx =rx;
fy = ry;
fz = headDist;
}
//draw the grid lines
void drawTunnel() {
float w = 1*(width/height);
float h = 1;
float offs = -1.0/5;
stroke(255);
float times = 20;
for (float wx = 0; wx <= w; wx += 1*(width/height) / (float)times) {
line(-wx, h, 0, -wx, h, times * offs);
line(-wx, -h, 0, -wx, -h, times * offs);
line(wx, h, 0, wx, h, times * offs);
line(wx, -h, 0, wx, -h, times * offs);
}
for (float hx = 0; hx <=h; hx += 1 / (float)times) {
line(-w, hx, 0, -w, hx, times * offs);
line(-w, -hx, 0, -w, -hx, times * offs);
line(w, hx, 0, w, hx, times * offs);
line(w, -hx, 0, w, -hx, times * offs);
}
int myColor = 255;
for (int i = 0; i <= times; i++) {
stroke(myColor);
myColor -= 7;
line(-w, h, i * offs, w, h, i*offs);
line(w, h, i * offs, w, -h, i*offs);
line(w, -h, i * offs, -w, -h, i*offs);
line(-w, -h, i * offs, -w, h, i*offs);
}
}
// SimpleOpenNI events
void onNewUser(int userId)
{
println("onNewUser - userId: " + userId);
println(" start pose detection");
if (true)
context.requestCalibrationSkeleton(userId, true);
else
context.startPoseDetection("Psi", userId);
}
void onLostUser(int userId)
{
println("onLostUser - userId: " + userId);
}
void onExitUser(int userId)
{
println("onExitUser - userId: " + userId);
}
void onReEnterUser(int userId)
{
println("onReEnterUser - userId: " + userId);
}
void onStartCalibration(int userId)
{
println("onStartCalibration - userId: " + userId);
}
void onEndCalibration(int userId, boolean successfull)
{
println("onEndCalibration - userId: " + userId + ", successfull: " + successfull);
if (successfull)
{
println(" User calibrated !!!");
context.startTrackingSkeleton(userId);
}
else
{
println(" Failed to calibrate user !!!");
println(" Start pose detection");
context.startPoseDetection("Psi", userId);
}
}
void onStartPose(String pose, int userId)
{
println("onStartPose - userId: " + userId + ", pose: " + pose);
println(" stop pose detection");
context.stopPoseDetection(userId);
context.requestCalibrationSkeleton(userId, true);
}
void onEndPose(String pose, int userId)
{
println("onEndPose - userId: " + userId + ", pose: " + pose);
}