Pass kinect as argument to class method?

Hi guys,

I’m trying to pass a kinect object in my ofApp.* to a method in a custom class MinDistance, but it doesn’t compile. My class header looks like this:

#ifndef _MINDISTANCE
#define _MINDISTANCE
#include "ofMain.h"

class MinDistance {
    public: 
        void setup();
        void update();
        void draw();

        int minDistX;
        int minDistY;

        MinDistance();

        ofxKinect kinect;

    private:
};
#endif

My implementation file looks like this:

#include "MinDistance.h"

MinDistance::MinDistance(){
}

void MinDistance::setup(ofxKinect _kinect){
    kinect = _kinect;
}

void MinDistance::update(){
    int w = 640;
    int h = 480;
    int step = 2;
    int minDistance = 3000;
    for(int x = 0; x < w; x+=step){
        for (int y = 0; y < h; y+=step){
            int kd = kinect.getDistanceAt(x, y);
            if (kd>0 && kd<minDistance) {
                minDistance = kd;
                minDistX = x;
                minDistY = y;
            } 
        }
    }
}

void MinDistance::draw(){
    ofNoFill;
    ofDrawCircle(
            ofMap(minDistX, 0, 640, 0, ofGetWidth()),
            ofMap(minDistY, 0, 480, 0, ofGetHeight()),
            24);
}

Which produces the following compiler error:

In file included from /home/kf/of/of_v0.11.0_linux64gcc6_release/apps/myApps/kinect/src/MinDistance.cpp:1:
/home/kf/of/of_v0.11.0_linux64gcc6_release/apps/myApps/kinect/src/MinDistance.h: At global scope:
/home/kf/of/of_v0.11.0_linux64gcc6_release/apps/myApps/kinect/src/MinDistance.h:16:9: error: ‘ofxKinect’ does not name a type
   16 |         ofxKinect kinect;
      |         ^~~~~~~~~
/home/kf/of/of_v0.11.0_linux64gcc6_release/apps/myApps/kinect/src/MinDistance.cpp:6:25: error: variable or field ‘setup’ declared void
    6 | void MinDistance::setup(ofxKinect _kinect){
      |                         ^~~~~~~~~
/home/kf/of/of_v0.11.0_linux64gcc6_release/apps/myApps/kinect/src/MinDistance.cpp:6:25: error: ‘ofxKinect’ was not declared in this scope
/home/kf/of/of_v0.11.0_linux64gcc6_release/apps/myApps/kinect/src/MinDistance.cpp: In member function ‘void MinDistance::update()’:
/home/kf/of/of_v0.11.0_linux64gcc6_release/apps/myApps/kinect/src/MinDistance.cpp:17:22: error: ‘kinect’ was not declared in this scope
   17 |             int kd = kinect.getDistanceAt(x, y);
      |                      ^~~~~~

The kinect and custom class is defined in the ofApp.h like this:

ofxKinect kinect;
MinDistance minDistance;       

… and I would like to be able to call it like this:

minDistance.setup(kinect);

Any and all help much appreciated!

K

Aha, solved it! (I think…) by subclassing ofxKinect. I am not at all sure this is the correct way to go about it, but it works now by including ofxKinect in the header file of my class, and redefining the class like this:

#ifndef _MINDISTANCE
#define _MINDISTANCE
#include "ofMain.h"
#include "ofxKinect.h"

class MinDistance : public ofxKinect {
    public: 
        void setup();
        void update(ofxKinect &kinect);
        void draw();

        int minDistX;
        int minDistY;

        MinDistance();

    private:
};
#endif

and the implementation file like this:

#include "MinDistance.h"

MinDistance::MinDistance(){
}

void MinDistance::setup(){
}

void MinDistance::update(ofxKinect &kinect){
    int w = 640;
    int h = 480;
    int step = 2;
    int minDistance = 3000;
    for(int x = 0; x < w; x+=step){
        for (int y = 0; y < h; y+=step){
            int kd = kinect.getDistanceAt(x, y);
            if (kd>0 && kd<minDistance) {
                minDistance = kd;
                minDistX = x;
                minDistY = y;
            } 
        }
    }
}

void MinDistance::draw(){
    ofNoFill;
    ofDrawCircle(
            ofMap(minDistX, 0, 640, 0, ofGetWidth()),
            ofMap(minDistY, 0, 480, 0, ofGetHeight()),
            24);
}

in c++ argument are passed by value. It means that when you do

void MinDistance::setup(ofxKinect _kinect){
    kinect = _kinect;
}

a new ofxKinect object is created by copying the passed kinect, and assigned to Kinect. This object is another indipendent thing from the one you are using into your ofApp.h and ofApp.cpp.

also, the error you got weren’t related to this bug, but to not having #include "ofxKinect.h" into your MinDistance.h

Ideally if you want to use the kinect you are using in main, you have to store it inside the class as a pointer, something like this:

#include "ofMain.h"

class MinDistance {
    public: 

        void setup(ofxKinect * _kinect);
        void update();
        void draw();

        int minDistX;
        int minDistY;

        MinDistance();

        ofxKinect * kinect;

    private:
};
#endif

implementation:

#include "MinDistance.h"

MinDistance::MinDistance(){
    kinect = nullptr;
}

void MinDistance::setup(ofxKinect * _kinect){
    this->kinect = _kinect;
}

void MinDistance::update(){
    int w = 640;
    int h = 480;
    int step = 2;
    int minDistance = 3000;
    for(int x = 0; x < w; x+=step){
        for (int y = 0; y < h; y+=step){
            int kd = kinect->getDistanceAt(x, y);
            if (kd>0 && kd<minDistance) {
                minDistance = kd;
                minDistX = x;
                minDistY = y;
            } 
        }
    }
}

void MinDistance::draw(){
    ofNoFill;
    ofDrawCircle(
            ofMap(minDistX, 0, 640, 0, ofGetWidth()),
            ofMap(minDistY, 0, 480, 0, ofGetHeight()),
            24);
}

note the use of kinect->getDistanceAt instead of kinect.getDistanceAt

remember to check out the ofBook chapter about pointer and references:
https://openframeworks.cc/ofBook/chapters/memory.html

@npisanti , thank you so very, very much! I’m still struggling with pointers and references, SuperCollider person that I am :slight_smile: This works perfectly. The only thing I had to figure out for myself was to put a ref to the kinect (not a pointer) int the ofApp.cpp call to minDistance.setup(). The class now looks like this (with some additional smoothing of the data):
MinDistance.h

#ifndef _MINDISTANCE
#define _MINDISTANCE
#include "ofMain.h"
#include "ofxKinect.h"

class MinDistance : public ofxKinect {
    public: 
        void setup(ofxKinect * _kinect);
        void update();
        void draw();

        float alpha = 0.9;
        ofVec2f prevMinDist; 
        ofVec2f minDist;

        MinDistance();

        ofxKinect * kinect;

    private:
};
#endif

MinDistance.cpp

#include "MinDistance.h"

MinDistance::MinDistance(){
    kinect = nullptr;
}

void MinDistance::setup(ofxKinect *_kinect){
    this->kinect = _kinect;
    prevMinDist.set(-1, -1);
}

void MinDistance::update(){
    int w = 640;
    int h = 480;
    int step = 2;
    int minDistance = 3000;
    for(int x = 0; x < w; x+=step){
        for (int y = 0; y < h; y+=step){
            int kd = kinect->getDistanceAt(x, y);
            if (kd>0 && kd<minDistance) {
                minDistance = kd;
                minDist.set(x, y);
            } 
        }
    }

    // smoothing
    minDist = minDist + alpha * (prevMinDist - minDist);
    prevMinDist = minDist; 
}

void MinDistance::draw(){
    ofNoFill();
    ofDrawCircle(
            ofMap(minDist.x, 0, 640, 0, ofGetWidth()),
            ofMap(minDist.y, 0, 480, 0, ofGetHeight()),
            24);
}