<commit_before>#include "ofApp.h"
#include "utils.h"
#define _USE_MATH_DEFINES
#include <cmath>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
int previewWidth = 640;
int previewHeight = 480;

DWORD features = FaceFrameFeatures::FaceFrameFeatures_BoundingBoxInColorSpace
| FaceFrameFeatures::FaceFrameFeatures_PointsInColorSpace
| FaceFrameFeatures::FaceFrameFeatures_RotationOrientation
| FaceFrameFeatures::FaceFrameFeatures_Happy
| FaceFrameFeatures::FaceFrameFeatures_RightEyeClosed
| FaceFrameFeatures::FaceFrameFeatures_LeftEyeClosed
| FaceFrameFeatures::FaceFrameFeatures_MouthOpen
| FaceFrameFeatures::FaceFrameFeatures_MouthMoved
| FaceFrameFeatures::FaceFrameFeatures_LookingAway
| FaceFrameFeatures::FaceFrameFeatures_Glasses
| FaceFrameFeatures::FaceFrameFeatures_FaceEngagement;

template<class Interface>
inline void SafeRelease(Interface *& pInterfaceToRelease)
{
	if (pInterfaceToRelease != NULL) {
		pInterfaceToRelease->Release();
		pInterfaceToRelease = NULL;
	}
}
inline void ExtractFaceRotationInDegrees(const Vector4* pQuaternion, int* pPitch, int* pYaw, int* pRoll)
{
	double x = pQuaternion->x;
	double y = pQuaternion->y;
	double z = pQuaternion->z;
	double w = pQuaternion->w;

	// convert face rotation quaternion to Euler angles in degrees
	*pPitch = static_cast<int>(std::atan2(2 * (y * z + w * x), w * w - x * x - y * y + z * z) / M_PI * 180.0f);
	*pYaw = static_cast<int>(std::asin(2 * (w * y - x * z)) / M_PI * 180.0f);
	*pRoll = static_cast<int>(std::atan2(2 * (x * y + w * z), w * w + x * x - y * y - z * z) / M_PI * 180.0f);
}
void ofApp::initFace() {
	for (int count = 0; count < BODY_COUNT; count++) {
		// Source
		HRESULT hResult = CreateFaceFrameSource(kinect.getSensor(), 0, features, &pFaceSource[count]);
		if (FAILED(hResult)) {
			std::cerr << "Error : CreateFaceFrameSource" << std::endl;
			return;
		}

		// Reader
		hResult = pFaceSource[count]->OpenReader(&pFaceReader[count]);
		if (FAILED(hResult)) {
			std::cerr << "Error : IFaceFrameSource::OpenReader()" << std::endl;
			return;
		}
	}
	// Face Property Table
	property[0] = "Happy";
	property[1] = "Engaged";
	property[2] = "WearingGlasses";
	property[3] = "LeftEyeClosed";
	property[4] = "RightEyeClosed";
	property[5] = "MouthOpen";
	property[6] = "MouthMoved";
	property[7] = "LookingAway";
}
//--------------------------------------------------------------
void ofApp::setup(){
	kinect.open();
	kinect.initDepthSource();
	kinect.initColorSource();
	kinect.initInfraredSource();
	kinect.initBodySource();
	kinect.initBodyIndexSource();
	initFace();
	ofSetWindowShape(previewWidth * 2, previewHeight * 2);
}

//--------------------------------------------------------------
void ofApp::update(){
	kinect.update();

	//while (1) {
		// Color Frame
		// acquire frame
		IColorFrame * pColorFrame = NULL;
		if (SUCCEEDED(kinect.getColorSource()->getReader()->AcquireLatestFrame(&pColorFrame))) {
			if (!SUCCEEDED(pColorFrame->CopyConvertedFrameDataToArray(kinect.getColorSource()->getPixels().size(), kinect.getColorSource()->getPixels(), ColorImageFormat_Bgra))) {
				std::cerr << "Couldn't pull pixel buffer" << std::endl;
			}
		}
		SafeRelease(pColorFrame);

		// Body Frame
		//cv::Point point[BODY_COUNT];
		IBodyFrame* pBodyFrame = nullptr;
		HRESULT hResult;
		while (1)
		{
			hResult = kinect.getBodySource()->getReader()->AcquireLatestFrame(&pBodyFrame);
			if (hResult == E_PENDING)
				continue;
			if (SUCCEEDED(hResult)) {
				IBody* pBody[BODY_COUNT] = { 0 };
				hResult = pBodyFrame->GetAndRefreshBodyData(BODY_COUNT, pBody);
				if (SUCCEEDED(hResult)) {
					for (int count = 0; count < BODY_COUNT; count++) {
						BOOLEAN bTracked = false;
						hResult = pBody[count]->get_IsTracked(&bTracked);
						if (SUCCEEDED(hResult) && bTracked) {
							/*// Joint
							Joint joint[JointType::JointType_Count];
							hResult = pBody[count]->GetJoints( JointType::JointType_Count, joint );
							if( SUCCEEDED( hResult ) ){
							for( int type = 0; type < JointType::JointType_Count; type++ ){
							ColorSpacePoint colorSpacePoint = { 0 };
							pCoordinateMapper->MapCameraPointToColorSpace( joint[type].Position, &colorSpacePoint );
							int x = static_cast<int>( colorSpacePoint.X );
							int y = static_cast<int>( colorSpacePoint.Y );
							if( ( x >= 0 ) && ( x < width ) && ( y >= 0 ) && ( y < height ) ){
							cv::circle( bufferMat, cv::Point( x, y ), 5, static_cast<cv::Scalar>( color[count] ), -1, CV_AA );
							}
							}
							}*/

							// Set TrackingID to Detect Face
							UINT64 trackingId = _UI64_MAX;
							hResult = pBody[count]->get_TrackingId(&trackingId);
							if (SUCCEEDED(hResult)) {
								pFaceSource[count]->put_TrackingId(trackingId);
							}
						}
					}
				}
				for (int count = 0; count < BODY_COUNT; count++) {
					SafeRelease(pBody[count]);
				}
				break;
			}
		}
		SafeRelease(pBodyFrame);

		// Face Frame
		//std::system("cls");
		for (int count = 0; count < BODY_COUNT; count++) {
			IFaceFrame* pFaceFrame = nullptr;
			hResult = pFaceReader[count]->AcquireLatestFrame(&pFaceFrame);
			if (SUCCEEDED(hResult) && pFaceFrame != nullptr) {
				BOOLEAN bFaceTracked = false;
				hResult = pFaceFrame->get_IsTrackingIdValid(&bFaceTracked);
				if (SUCCEEDED(hResult) && bFaceTracked) {
					IFaceFrameResult* pFaceResult = nullptr;
					hResult = pFaceFrame->get_FaceFrameResult(&pFaceResult);
					if (SUCCEEDED(hResult) && pFaceResult != nullptr) {
						std::vector<std::string> result;

						// Face Point
						PointF facePoint[FacePointType::FacePointType_Count];
						hResult = pFaceResult->GetFacePointsInColorSpace(FacePointType::FacePointType_Count, facePoint);
						if (SUCCEEDED(hResult)) {
							/*
							cv::circle(bufferMat, cv::Point(static_cast<int>(facePoint[0].X), static_cast<int>(facePoint[0].Y)), 5, static_cast<cv::Scalar>(color[count]), -1, CV_AA); // Eye (Left)
							cv::circle(bufferMat, cv::Point(static_cast<int>(facePoint[1].X), static_cast<int>(facePoint[1].Y)), 5, static_cast<cv::Scalar>(color[count]), -1, CV_AA); // Eye (Right)
							cv::circle(bufferMat, cv::Point(static_cast<int>(facePoint[2].X), static_cast<int>(facePoint[2].Y)), 5, static_cast<cv::Scalar>(color[count]), -1, CV_AA); // Nose
							cv::circle(bufferMat, cv::Point(static_cast<int>(facePoint[3].X), static_cast<int>(facePoint[3].Y)), 5, static_cast<cv::Scalar>(color[count]), -1, CV_AA); // Mouth (Left)
							cv::circle(bufferMat, cv::Point(static_cast<int>(facePoint[4].X), static_cast<int>(facePoint[4].Y)), 5, static_cast<cv::Scalar>(color[count]), -1, CV_AA); // Mouth (Right)
							*/
						}

						// Face Bounding Box test
						RectI boundingBox;
						hResult = pFaceResult->get_FaceBoundingBoxInColorSpace(&boundingBox);
						if (SUCCEEDED(hResult)) {
							//cv::rectangle(bufferMat, cv::Rect(boundingBox.Left, boundingBox.Top, boundingBox.Right - boundingBox.Left, boundingBox.Bottom - boundingBox.Top), static_cast<cv::Scalar>(color[count]));
						}

						// Face Rotation
						Vector4 faceRotation;
						hResult = pFaceResult->get_FaceRotationQuaternion(&faceRotation);
						if (SUCCEEDED(hResult)) {
							int pitch, yaw, roll;
							ExtractFaceRotationInDegrees(&faceRotation, &pitch, &yaw, &roll);
							result.push_back("Pitch, Yaw, Roll : " + std::to_string(pitch) + ", " + std::to_string(yaw) + ", " + std::to_string(roll));
						}

						// Face Property
						DetectionResult faceProperty[FaceProperty::FaceProperty_Count];
						hResult = pFaceResult->GetFaceProperties(FaceProperty::FaceProperty_Count, faceProperty);
						if (SUCCEEDED(hResult)) {
							for (int count = 0; count < FaceProperty::FaceProperty_Count; count++) {
								switch (faceProperty[count]) {
								case DetectionResult::DetectionResult_Unknown:
									result.push_back(property[count] + " : Unknown");
									break;
								case DetectionResult::DetectionResult_Yes:
									result.push_back(property[count] + " : Yes");
									break;
								case DetectionResult::DetectionResult_No:
									result.push_back(property[count] + " : No");
									break;
								case DetectionResult::DetectionResult_Maybe:
									result.push_back(property[count] + " : Mayby");
									break;
								default:
									break;
								}
							}
						}

						if (boundingBox.Left && boundingBox.Bottom) {
							int offset = 30;
							for (std::vector<std::string>::iterator it = result.begin(); it != result.end(); it++, offset += 30) {
								//cv::putText(bufferMat, *it, cv::Point(boundingBox.Left, boundingBox.Bottom + offset), cv::FONT_HERSHEY_COMPLEX, 1.0f, static_cast<cv::Scalar>(color[count]), 2, CV_AA);
							}
						}
					}
					SafeRelease(pFaceResult);
				}
			}
			SafeRelease(pFaceFrame);
		}

	//--
	//Getting joint positions (skeleton tracking)
	//--
	//
	{
		auto bodies = kinect.getBodySource()->getBodies();
		for (auto body : bodies) {
			for (auto joint : body.joints) {
				//now do something with the joints
			}
		}
	}
	//
	//--

	//--
	//Getting bones (connected joints)
	//--
	//
	{
		// Note that for this we need a reference of which joints are connected to each other.
		// We call this the 'boneAtlas', and you can ask for a reference to this atlas whenever you like
		auto bodies = kinect.getBodySource()->getBodies();
		auto boneAtlas = ofxKinectForWindows2::Data::Body::getBonesAtlas();

		for (auto body : bodies) {
			for (auto bone : boneAtlas) {
				auto firstJointInBone = body.joints[bone.first];
				auto secondJointInBone = body.joints[bone.second];

				//now do something with the joints
			}
		}
	}
	//
	//--
}

//--------------------------------------------------------------
void ofApp::draw(){
	kinect.getDepthSource()->draw(0, 0, previewWidth, previewHeight);  // note that the depth texture is RAW so may appear dark

																	   // Color is at 1920x1080 instead of 512x424 so we should fix aspect ratio
	float colorHeight = previewWidth * (kinect.getColorSource()->getHeight() / kinect.getColorSource()->getWidth());
	float colorTop = (previewHeight - colorHeight) / 2.0;

	kinect.getColorSource()->draw(previewWidth, 0 + colorTop, previewWidth, colorHeight);
	kinect.getBodySource()->drawProjected(previewWidth, 0 + colorTop, previewWidth, colorHeight);

	kinect.getInfraredSource()->draw(0, previewHeight, previewWidth, previewHeight);

	kinect.getBodyIndexSource()->draw(previewWidth, previewHeight, previewWidth, previewHeight);
	kinect.getBodySource()->drawProjected(previewWidth, previewHeight, previewWidth, previewHeight, ofxKFW2::ProjectionCoordinates::DepthCamera);
}

//--------------------------------------------------------------
void ofApp::keyPressed(int key){

}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseEntered(int x, int y){

}

//--------------------------------------------------------------
void ofApp::mouseExited(int x, int y){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){

}
<commit_msg>basic face drawing<commit_after>#include "ofApp.h"
#include "utils.h"
#define _USE_MATH_DEFINES
#include <cmath>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
int previewWidth = 640;
int previewHeight = 480;

DWORD features = FaceFrameFeatures::FaceFrameFeatures_BoundingBoxInColorSpace
| FaceFrameFeatures::FaceFrameFeatures_PointsInColorSpace
| FaceFrameFeatures::FaceFrameFeatures_RotationOrientation
| FaceFrameFeatures::FaceFrameFeatures_Happy
| FaceFrameFeatures::FaceFrameFeatures_RightEyeClosed
| FaceFrameFeatures::FaceFrameFeatures_LeftEyeClosed
| FaceFrameFeatures::FaceFrameFeatures_MouthOpen
| FaceFrameFeatures::FaceFrameFeatures_MouthMoved
| FaceFrameFeatures::FaceFrameFeatures_LookingAway
| FaceFrameFeatures::FaceFrameFeatures_Glasses
| FaceFrameFeatures::FaceFrameFeatures_FaceEngagement;

PointF facePoint[FacePointType::FacePointType_Count];
bool drawface = false;

template<class Interface>
inline void SafeRelease(Interface *& pInterfaceToRelease)
{
	if (pInterfaceToRelease != NULL) {
		pInterfaceToRelease->Release();
		pInterfaceToRelease = NULL;
	}
}
inline void ExtractFaceRotationInDegrees(const Vector4* pQuaternion, int* pPitch, int* pYaw, int* pRoll)
{
	double x = pQuaternion->x;
	double y = pQuaternion->y;
	double z = pQuaternion->z;
	double w = pQuaternion->w;

	// convert face rotation quaternion to Euler angles in degrees
	*pPitch = static_cast<int>(std::atan2(2 * (y * z + w * x), w * w - x * x - y * y + z * z) / M_PI * 180.0f);
	*pYaw = static_cast<int>(std::asin(2 * (w * y - x * z)) / M_PI * 180.0f);
	*pRoll = static_cast<int>(std::atan2(2 * (x * y + w * z), w * w + x * x - y * y - z * z) / M_PI * 180.0f);
}
void ofApp::initFace() {
	for (int count = 0; count < BODY_COUNT; count++) {
		// Source
		HRESULT hResult = CreateFaceFrameSource(kinect.getSensor(), 0, features, &pFaceSource[count]);
		if (FAILED(hResult)) {
			std::cerr << "Error : CreateFaceFrameSource" << std::endl;
			return;
		}

		// Reader
		hResult = pFaceSource[count]->OpenReader(&pFaceReader[count]);
		if (FAILED(hResult)) {
			std::cerr << "Error : IFaceFrameSource::OpenReader()" << std::endl;
			return;
		}
	}
	// Face Property Table
	property[0] = "Happy";
	property[1] = "Engaged";
	property[2] = "WearingGlasses";
	property[3] = "LeftEyeClosed";
	property[4] = "RightEyeClosed";
	property[5] = "MouthOpen";
	property[6] = "MouthMoved";
	property[7] = "LookingAway";
}
//--------------------------------------------------------------
void ofApp::setup(){
	kinect.open();
	kinect.initDepthSource();
	kinect.initColorSource();
	kinect.initInfraredSource();
	kinect.initBodySource();
	kinect.initBodyIndexSource();
	initFace();
	ofSetWindowShape(previewWidth * 2, previewHeight * 2);
}

//--------------------------------------------------------------
void ofApp::update(){
	kinect.update();

	//while (1) {
		// Color Frame
		// acquire frame
		IColorFrame * pColorFrame = NULL;
		if (SUCCEEDED(kinect.getColorSource()->getReader()->AcquireLatestFrame(&pColorFrame))) {
			if (!SUCCEEDED(pColorFrame->CopyConvertedFrameDataToArray(kinect.getColorSource()->getPixels().size(), kinect.getColorSource()->getPixels(), ColorImageFormat_Bgra))) {
				std::cerr << "Couldn't pull pixel buffer" << std::endl;
			}
		}
		SafeRelease(pColorFrame);

		// Body Frame
		//cv::Point point[BODY_COUNT];
		IBodyFrame* pBodyFrame = nullptr;
		HRESULT hResult;
		while (1)
		{
			hResult = kinect.getBodySource()->getReader()->AcquireLatestFrame(&pBodyFrame);
			if (hResult == E_PENDING)
				continue;
			if (SUCCEEDED(hResult)) {
				IBody* pBody[BODY_COUNT] = { 0 };
				hResult = pBodyFrame->GetAndRefreshBodyData(BODY_COUNT, pBody);
				if (SUCCEEDED(hResult)) {
					for (int count = 0; count < BODY_COUNT; count++) {
						BOOLEAN bTracked = false;
						hResult = pBody[count]->get_IsTracked(&bTracked);
						if (SUCCEEDED(hResult) && bTracked) {
							/*// Joint
							Joint joint[JointType::JointType_Count];
							hResult = pBody[count]->GetJoints( JointType::JointType_Count, joint );
							if( SUCCEEDED( hResult ) ){
							for( int type = 0; type < JointType::JointType_Count; type++ ){
							ColorSpacePoint colorSpacePoint = { 0 };
							pCoordinateMapper->MapCameraPointToColorSpace( joint[type].Position, &colorSpacePoint );
							int x = static_cast<int>( colorSpacePoint.X );
							int y = static_cast<int>( colorSpacePoint.Y );
							if( ( x >= 0 ) && ( x < width ) && ( y >= 0 ) && ( y < height ) ){
							cv::circle( bufferMat, cv::Point( x, y ), 5, static_cast<cv::Scalar>( color[count] ), -1, CV_AA );
							}
							}
							}*/

							// Set TrackingID to Detect Face
							UINT64 trackingId = _UI64_MAX;
							hResult = pBody[count]->get_TrackingId(&trackingId);
							if (SUCCEEDED(hResult)) {
								pFaceSource[count]->put_TrackingId(trackingId);
							}
						}
					}
				}
				for (int count = 0; count < BODY_COUNT; count++) {
					SafeRelease(pBody[count]);
				}
				break;
			}
		}
		SafeRelease(pBodyFrame);

		// Face Frame
		//std::system("cls");
		for (int count = 0; count < BODY_COUNT; count++) {
			IFaceFrame* pFaceFrame = nullptr;
			hResult = pFaceReader[count]->AcquireLatestFrame(&pFaceFrame);
			if (SUCCEEDED(hResult) && pFaceFrame != nullptr) {
				BOOLEAN bFaceTracked = false;
				hResult = pFaceFrame->get_IsTrackingIdValid(&bFaceTracked);
				if (SUCCEEDED(hResult) && bFaceTracked) {
					IFaceFrameResult* pFaceResult = nullptr;
					hResult = pFaceFrame->get_FaceFrameResult(&pFaceResult);
					if (SUCCEEDED(hResult) && pFaceResult != nullptr) {
						std::vector<std::string> result;

						// Face Point
						hResult = pFaceResult->GetFacePointsInColorSpace(FacePointType::FacePointType_Count, facePoint);
						if (SUCCEEDED(hResult)) {
							drawface = true;
							/*
							cv::circle(bufferMat, cv::Point(static_cast<int>(facePoint[0].X), static_cast<int>(facePoint[0].Y)), 5, static_cast<cv::Scalar>(color[count]), -1, CV_AA); // Eye (Left)
							cv::circle(bufferMat, cv::Point(static_cast<int>(facePoint[1].X), static_cast<int>(facePoint[1].Y)), 5, static_cast<cv::Scalar>(color[count]), -1, CV_AA); // Eye (Right)
							cv::circle(bufferMat, cv::Point(static_cast<int>(facePoint[2].X), static_cast<int>(facePoint[2].Y)), 5, static_cast<cv::Scalar>(color[count]), -1, CV_AA); // Nose
							cv::circle(bufferMat, cv::Point(static_cast<int>(facePoint[3].X), static_cast<int>(facePoint[3].Y)), 5, static_cast<cv::Scalar>(color[count]), -1, CV_AA); // Mouth (Left)
							cv::circle(bufferMat, cv::Point(static_cast<int>(facePoint[4].X), static_cast<int>(facePoint[4].Y)), 5, static_cast<cv::Scalar>(color[count]), -1, CV_AA); // Mouth (Right)
							*/
						}

						// Face Bounding Box test
						RectI boundingBox;
						hResult = pFaceResult->get_FaceBoundingBoxInColorSpace(&boundingBox);
						if (SUCCEEDED(hResult)) {
							//cv::rectangle(bufferMat, cv::Rect(boundingBox.Left, boundingBox.Top, boundingBox.Right - boundingBox.Left, boundingBox.Bottom - boundingBox.Top), static_cast<cv::Scalar>(color[count]));
						}

						// Face Rotation
						Vector4 faceRotation;
						hResult = pFaceResult->get_FaceRotationQuaternion(&faceRotation);
						if (SUCCEEDED(hResult)) {
							int pitch, yaw, roll;
							ExtractFaceRotationInDegrees(&faceRotation, &pitch, &yaw, &roll);
							result.push_back("Pitch, Yaw, Roll : " + std::to_string(pitch) + ", " + std::to_string(yaw) + ", " + std::to_string(roll));
						}

						// Face Property
						DetectionResult faceProperty[FaceProperty::FaceProperty_Count];
						hResult = pFaceResult->GetFaceProperties(FaceProperty::FaceProperty_Count, faceProperty);
						if (SUCCEEDED(hResult)) {
							for (int count = 0; count < FaceProperty::FaceProperty_Count; count++) {
								switch (faceProperty[count]) {
								case DetectionResult::DetectionResult_Unknown:
									result.push_back(property[count] + " : Unknown");
									break;
								case DetectionResult::DetectionResult_Yes:
									result.push_back(property[count] + " : Yes");
									break;
								case DetectionResult::DetectionResult_No:
									result.push_back(property[count] + " : No");
									break;
								case DetectionResult::DetectionResult_Maybe:
									result.push_back(property[count] + " : Mayby");
									break;
								default:
									break;
								}
							}
						}

						if (boundingBox.Left && boundingBox.Bottom) {
							int offset = 30;
							for (std::vector<std::string>::iterator it = result.begin(); it != result.end(); it++, offset += 30) {
								//cv::putText(bufferMat, *it, cv::Point(boundingBox.Left, boundingBox.Bottom + offset), cv::FONT_HERSHEY_COMPLEX, 1.0f, static_cast<cv::Scalar>(color[count]), 2, CV_AA);
							}
						}
					}
					SafeRelease(pFaceResult);
				}
			}
			SafeRelease(pFaceFrame);
		}

	//--
	//Getting joint positions (skeleton tracking)
	//--
	//
	{
		auto bodies = kinect.getBodySource()->getBodies();
		for (auto body : bodies) {
			for (auto joint : body.joints) {
				//now do something with the joints
			}
		}
	}
	//
	//--

	//--
	//Getting bones (connected joints)
	//--
	//
	{
		// Note that for this we need a reference of which joints are connected to each other.
		// We call this the 'boneAtlas', and you can ask for a reference to this atlas whenever you like
		auto bodies = kinect.getBodySource()->getBodies();
		auto boneAtlas = ofxKinectForWindows2::Data::Body::getBonesAtlas();

		for (auto body : bodies) {
			for (auto bone : boneAtlas) {
				auto firstJointInBone = body.joints[bone.first];
				auto secondJointInBone = body.joints[bone.second];

				//now do something with the joints
			}
		}
	}
	//
	//--
}

//--------------------------------------------------------------
void ofApp::draw(){
	kinect.getDepthSource()->draw(0, 0, previewWidth, previewHeight);  // note that the depth texture is RAW so may appear dark

																	   // Color is at 1920x1080 instead of 512x424 so we should fix aspect ratio
	float colorHeight = previewWidth * (kinect.getColorSource()->getHeight() / kinect.getColorSource()->getWidth());
	float colorTop = (previewHeight - colorHeight) / 2.0;

	kinect.getColorSource()->draw(previewWidth, 0 + colorTop, previewWidth, colorHeight);
	kinect.getBodySource()->drawProjected(previewWidth, 0 + colorTop, previewWidth, colorHeight);

	kinect.getInfraredSource()->draw(0, previewHeight, previewWidth, previewHeight);

	kinect.getBodyIndexSource()->draw(previewWidth, previewHeight, previewWidth, previewHeight);
	kinect.getBodySource()->drawProjected(previewWidth, previewHeight, previewWidth, previewHeight, ofxKFW2::ProjectionCoordinates::DepthCamera);

	if (drawface) {
		ofDrawCircle(facePoint[0].X, facePoint[0].Y, 5);
		ofDrawCircle(facePoint[1].X, facePoint[1].Y, 5);
		ofDrawCircle(facePoint[2].X, facePoint[2].Y, 5);
		ofDrawCircle(facePoint[3].X, facePoint[3].Y, 5);
		ofDrawCircle(facePoint[4].X, facePoint[4].Y, 5);
	}

}

//--------------------------------------------------------------
void ofApp::keyPressed(int key){

}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseEntered(int x, int y){

}

//--------------------------------------------------------------
void ofApp::mouseExited(int x, int y){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){

}
<|endoftext|>


<commit_before>#include "ofApp.h"
#include <opencv2/opencv.hpp>

using namespace ofxCv;
using namespace cv;

void ofApp::onCharacterReceived(SSHKeyListenerEventData& e)
{
	keyPressed((int)e.character);
}
//--------------------------------------------------------------
void ofApp::setup(){

    ofLog() << "RPid " << RPiId;
    gui.setup("panel");
    gui.setPosition(650,10);
    gui.add(cutDown.set( "cutDown", 110, 1, 255 ));
    gui.add(fps.set("fps", 16, 1, 30));
    gui.add(learningTime.set("learningTime",100,1,1000));
    gui.add(backgroundThreshold.set("backgroundThreshold",15,1,300));
    gui.add(erodeFactor.set("erodeFactor",0,0,3));
    gui.add(dilateFactor.set("dilateFactor",0,0,3));
    gui.add(medianBlurFactor.set("medianBlur",1,0,5));
    gui.add(minContourArea.set("minContourArea",20, 5, 40));
    gui.add(maxContourArea.set("maxContourArea",(160*120)/3,40, 160*120)); // one third of the screen.
    gui.add(maxContours.set("maxContours", 5, 1, 10));
    ofSetFrameRate(fps);

    /*filename_save = "RPi_" + RPiId + "_params";

    if(ofFile::doesFileExist(filename_save)){
        ofLog(OF_LOG_NOTICE)<< "loading from file" + filename_save << endl;
        gui.loadFromFile(filename_save);
    }*/

    consoleListener.setup(this);
    consoleListener.startThread(false, false);

    background.setLearningTime(learningTime);
    background.setThresholdValue(backgroundThreshold);

    fps.addListener(this, &ofApp::fpsChanged);
    learningTime.addListener(this, &ofApp::learningTimeChanged);
    backgroundThreshold.addListener(this, &ofApp::backgroundThresholdChanged);

#ifdef __arm__
    cam.setup(160,120,false);//setup camera (w,h,color = true,gray = false);
    cam.setExposureMode(MMAL_PARAM_EXPOSUREMODE_FIXEDFPS);
    //cam.setExposureCompensation(0);
    //cam.setAWBMode(MMAL_PARAM_AWBMODE_OFF);
    //cam.setExposureCompensation(0);
#else
    cam.initGrabber(160,120);
#endif

    sender.setup("192.168.255.255", 8000);
    //sender.setup("127.0.0.1", 8000);
 	receiver.setup(OSC_PORT);
}

static int framenr = 1;

//--------------------------------------------------------------
void ofApp::update(){
    framenr++;
#ifdef __arm__
    frame = Mat(cam.grab());
    stringstream ss;
    ss << "rpi_" << RPiId << ".png";
    if(framenr % 100 == 0) {
      toOf(frame,tosave);

      ofSaveImage(tosave, ss.str());
    }
#else
    ofImage image;

    stringstream filename;
    filename << "file" << framenr << ".png";
    image.loadImage(filename.str());
    image.rotate90(2);
    frame = toCv(image);

#endif

    if (framenr == 130) {
        background.reset();
    }

    if (!frame.empty()) {

        //threshold( frame, frame, cutDown, 255,2 );

        background.update(frame, thresholded);
        thresholded.update();

        frameProcessed = toCv(thresholded);
        medianBlur ( frameProcessed, frameProcessed, medianBlurFactor );
        erode( frameProcessed, frameProcessed, erodeFactor );
        dilate( frameProcessed, frameProcessed, dilateFactor );

        ofPixels pix;
        ofImage img;
        toOf(frameProcessed, pix);
        grayImage.setFromPixels(pix);

        contourFinder.findContours(grayImage, minContourArea, maxContourArea, maxContours, true); // find holes

        ofxOscMessage numContours;
        stringstream addr;
        addr << "/RPi_" << RPiId << "/total_contours/";
        numContours.setAddress(addr.str());
        numContours.addIntArg(contourFinder.nBlobs);
        sender.sendMessage(numContours);

        for (int i = 0; i < contourFinder.nBlobs; i++){

            ofxOscMessage message;
            stringstream messageAddress;
            messageAddress << "/RPi_" << RPiId << "/contour_" << (i + 1) << "/";
            message.setAddress(messageAddress.str());
            float x = contourFinder.blobs[i].boundingRect.x;
            float y = contourFinder.blobs[i].boundingRect.y;
            float width = contourFinder.blobs[i].boundingRect.width;
            float height = contourFinder.blobs[i].boundingRect.height;

            //normalization
            x = x / 160;
            y = y / 120;
            width = width / 160;
            height = height / 120;

            //openGl standard
            x = x + width/2;
            y = y + height /2;
            x = x * 2 - 1;
            y = y * -2 + 1;
            width*=2;
            height*=2;

            message.addFloatArg(x);
            message.addFloatArg(y);
            message.addFloatArg(width);
            message.addFloatArg(height);

            sender.sendMessage(message);
            //ofLog() << x << " and " << y;
        }
    }
	// hide old messages
	for(int i = 0; i < NUM_MSG_STRINGS; i++){
		if(timers[i] < ofGetElapsedTimef()){
			msg_strings[i] = "";
		}
	}

	// check for waiting messages
	while(receiver.hasWaitingMessages()){
		// get the next message
		ofxOscMessage rm;//receivedMessage
		ofxOscMessage sm;//sentMessage
		receiver.getNextMessage(&rm);
                //probably we need to move it out of the update
           /* if(rm.getAddress() == "/save"){

                gui.saveToFile(filename_save);
            }*/
            if(rm.getAddress() == "/getParams"){
                sm.setAddress("/allParams");
                sm.addStringArg(RPiId);
                sm.addIntArg(cutDown);
                sm.addIntArg(fps);
                sm.addIntArg(learningTime);
                sm.addIntArg(backgroundThreshold);
                sm.addIntArg(erodeFactor);
                sm.addIntArg(dilateFactor);
                sm.addIntArg(medianBlurFactor);
                sm.addIntArg(minContourArea);
                sm.addIntArg(maxContourArea);
                sm.addIntArg(maxContours);

                sender.sendMessage(sm);
            }
            else if(rm.getAddress() == "/whoIsThere"){
                sm.setAddress("/RPiId");
                sm.addStringArg(RPiId);
                sender.sendMessage(sm);
            }
            else if(rm.getAddress() == "/cutDown" + RPiId){
                cutDown = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/fps" + RPiId){
                fps = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/learningTime" + RPiId){
                learningTime = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/backgroundThreshold" + RPiId){
                backgroundThreshold = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/erodeFactor" + RPiId){
                erodeFactor = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/dilateFactor" + RPiId){
                dilateFactor = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/medianBlurFactor" + RPiId){
                medianBlurFactor = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/minContourArea" + RPiId){
                minContourArea = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/maxContourArea" + RPiId){
                maxContourArea = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/maxContours" + RPiId){
                maxContours = rm.getArgAsInt32(0);
            }
	}
}

//-- Parameters events listeners

void ofApp::fpsChanged(int &fps) {
    ofSetFrameRate(fps);
}

void ofApp::learningTimeChanged(int &learningTime) {
    background.setLearningTime(learningTime);
}

void ofApp::backgroundThresholdChanged(int &backgroundThreshold) {
    background.setThresholdValue(backgroundThreshold);
}

//--------------------------------------------------------------
void ofApp::draw(){
//#ifdef __arm__
    drawMat(frame,0,0,320,240);
    drawMat(frameProcessed,0,240,320,240);
    thresholded.draw(320, 0,320,240);

    contourFinder.draw(320,240,320,240);

    gui.draw();
//#endif
}

//--------------------------------------------------------------
void ofApp::keyPressed  (int key){
    ofLogVerbose() << "keyPressed: " << key;

    if(key == ' ') {
        background.reset();
    }

    if(key == 'r') {
        framenr = 1;
        ofLog()<< "restarting video";
    }
}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){
    //thresh = ofMap(x,0,ofGetWidth(),0,255);
}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){

}
<commit_msg>added reset Background through OSC<commit_after>#include "ofApp.h"
#include <opencv2/opencv.hpp>

using namespace ofxCv;
using namespace cv;

void ofApp::onCharacterReceived(SSHKeyListenerEventData& e)
{
	keyPressed((int)e.character);
}
//--------------------------------------------------------------
void ofApp::setup(){

    ofLog() << "RPid " << RPiId;
    gui.setup("panel");
    gui.setPosition(650,10);
    gui.add(cutDown.set( "cutDown", 110, 1, 255 ));
    gui.add(fps.set("fps", 16, 1, 30));
    gui.add(learningTime.set("learningTime",100,1,1000));
    gui.add(backgroundThreshold.set("backgroundThreshold",15,1,300));
    gui.add(erodeFactor.set("erodeFactor",0,0,3));
    gui.add(dilateFactor.set("dilateFactor",0,0,3));
    gui.add(medianBlurFactor.set("medianBlur",1,0,5));
    gui.add(minContourArea.set("minContourArea",20, 5, 40));
    gui.add(maxContourArea.set("maxContourArea",(160*120)/3,40, 160*120)); // one third of the screen.
    gui.add(maxContours.set("maxContours", 5, 1, 10));
    ofSetFrameRate(fps);

    /*filename_save = "RPi_" + RPiId + "_params";

    if(ofFile::doesFileExist(filename_save)){
        ofLog(OF_LOG_NOTICE)<< "loading from file" + filename_save << endl;
        gui.loadFromFile(filename_save);
    }*/

    consoleListener.setup(this);
    consoleListener.startThread(false, false);

    background.setLearningTime(learningTime);
    background.setThresholdValue(backgroundThreshold);

    fps.addListener(this, &ofApp::fpsChanged);
    learningTime.addListener(this, &ofApp::learningTimeChanged);
    backgroundThreshold.addListener(this, &ofApp::backgroundThresholdChanged);

#ifdef __arm__
    cam.setup(160,120,false);//setup camera (w,h,color = true,gray = false);
    cam.setExposureMode(MMAL_PARAM_EXPOSUREMODE_FIXEDFPS);
    //cam.setExposureCompensation(0);
    //cam.setAWBMode(MMAL_PARAM_AWBMODE_OFF);
    //cam.setExposureCompensation(0);
#else
    cam.initGrabber(160,120);
#endif

    sender.setup("192.168.255.255", 8000);
    //sender.setup("127.0.0.1", 8000);
 	receiver.setup(OSC_PORT);
}

static int framenr = 1;

//--------------------------------------------------------------
void ofApp::update(){
    framenr++;
#ifdef __arm__
    frame = Mat(cam.grab());
    stringstream ss;
    ss << "rpi_" << RPiId << ".png";
    if(framenr % 100 == 0) {
      toOf(frame,tosave);

      ofSaveImage(tosave, ss.str());
    }
#else
    ofImage image;

    stringstream filename;
    filename << "file" << framenr << ".png";
    image.loadImage(filename.str());
    image.rotate90(2);
    frame = toCv(image);

#endif

    if (framenr == 130) {
        background.reset();
    }

    if (!frame.empty()) {

        //threshold( frame, frame, cutDown, 255,2 );

        background.update(frame, thresholded);
        thresholded.update();

        frameProcessed = toCv(thresholded);
        medianBlur ( frameProcessed, frameProcessed, medianBlurFactor );
        erode( frameProcessed, frameProcessed, erodeFactor );
        dilate( frameProcessed, frameProcessed, dilateFactor );

        ofPixels pix;
        ofImage img;
        toOf(frameProcessed, pix);
        grayImage.setFromPixels(pix);

        contourFinder.findContours(grayImage, minContourArea, maxContourArea, maxContours, true); // find holes

        ofxOscMessage numContours;
        stringstream addr;
        addr << "/RPi_" << RPiId << "/total_contours/";
        numContours.setAddress(addr.str());
        numContours.addIntArg(contourFinder.nBlobs);
        sender.sendMessage(numContours);

        for (int i = 0; i < contourFinder.nBlobs; i++){

            ofxOscMessage message;
            stringstream messageAddress;
            messageAddress << "/RPi_" << RPiId << "/contour_" << (i + 1) << "/";
            message.setAddress(messageAddress.str());
            float x = contourFinder.blobs[i].boundingRect.x;
            float y = contourFinder.blobs[i].boundingRect.y;
            float width = contourFinder.blobs[i].boundingRect.width;
            float height = contourFinder.blobs[i].boundingRect.height;

            //normalization
            x = x / 160;
            y = y / 120;
            width = width / 160;
            height = height / 120;

            //openGl standard
            x = x + width/2;
            y = y + height /2;
            x = x * 2 - 1;
            y = y * -2 + 1;
            width*=2;
            height*=2;

            message.addFloatArg(x);
            message.addFloatArg(y);
            message.addFloatArg(width);
            message.addFloatArg(height);

            sender.sendMessage(message);
            //ofLog() << x << " and " << y;
        }
    }
	// hide old messages
	for(int i = 0; i < NUM_MSG_STRINGS; i++){
		if(timers[i] < ofGetElapsedTimef()){
			msg_strings[i] = "";
		}
	}

	// check for waiting messages
	while(receiver.hasWaitingMessages()){
		// get the next message
		ofxOscMessage rm;//receivedMessage
		ofxOscMessage sm;//sentMessage
		receiver.getNextMessage(&rm);
                //probably we need to move it out of the update
           /* if(rm.getAddress() == "/save"){

                gui.saveToFile(filename_save);
            }*/
            if(rm.getAddress() == "/getParams"){
                sm.setAddress("/allParams");
                sm.addStringArg(RPiId);
                sm.addIntArg(cutDown);
                sm.addIntArg(fps);
                sm.addIntArg(learningTime);
                sm.addIntArg(backgroundThreshold);
                sm.addIntArg(erodeFactor);
                sm.addIntArg(dilateFactor);
                sm.addIntArg(medianBlurFactor);
                sm.addIntArg(minContourArea);
                sm.addIntArg(maxContourArea);
                sm.addIntArg(maxContours);

                sender.sendMessage(sm);
            }
            else if(rm.getAddress() == "/whoIsThere"){
                sm.setAddress("/RPiId");
                sm.addStringArg(RPiId);
                sender.sendMessage(sm);
            }
            else if(rm.getAddress() == "/cutDown" + RPiId){
                cutDown = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/fps" + RPiId){
                fps = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/learningTime" + RPiId){
                learningTime = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/backgroundThreshold" + RPiId){
                backgroundThreshold = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/erodeFactor" + RPiId){
                erodeFactor = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/dilateFactor" + RPiId){
                dilateFactor = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/medianBlurFactor" + RPiId){
                medianBlurFactor = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/minContourArea" + RPiId){
                minContourArea = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/maxContourArea" + RPiId){
                maxContourArea = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/maxContours" + RPiId){
                maxContours = rm.getArgAsInt32(0);
            }
			else if(rm.getAddress() == "/resetBG" + RPiId){
				background.reset();
			}

	}
}

//-- Parameters events listeners

void ofApp::fpsChanged(int &fps) {
    ofSetFrameRate(fps);
}

void ofApp::learningTimeChanged(int &learningTime) {
    background.setLearningTime(learningTime);
}

void ofApp::backgroundThresholdChanged(int &backgroundThreshold) {
    background.setThresholdValue(backgroundThreshold);
}

//--------------------------------------------------------------
void ofApp::draw(){
//#ifdef __arm__
    drawMat(frame,0,0,320,240);
    drawMat(frameProcessed,0,240,320,240);
    thresholded.draw(320, 0,320,240);

    contourFinder.draw(320,240,320,240);

    gui.draw();
//#endif
}

//--------------------------------------------------------------
void ofApp::keyPressed  (int key){
    ofLogVerbose() << "keyPressed: " << key;

    if(key == ' ') {
        background.reset();
    }

    if(key == 'r') {
        framenr = 1;
        ofLog()<< "restarting video";
    }
}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){
    //thresh = ofMap(x,0,ofGetWidth(),0,255);
}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){

}
<|endoftext|>


<commit_before>#include "ofApp.h"
#include <opencv2/opencv.hpp>

using namespace ofxCv;
using namespace cv;

void ofApp::onCharacterReceived(SSHKeyListenerEventData& e)
{
	keyPressed((int)e.character);
}
//--------------------------------------------------------------
void ofApp::setup(){

    ofLog() << "RPid " << RPiId;
    gui.setup("panel");
    gui.setPosition(650,10);
    gui.add(cutDown.set( "cutDown", 110, 1, 255 ));
    gui.add(fps.set("fps", 16, 1, 30));
    gui.add(learningTime.set("learningTime",100,1,1000));
    gui.add(backgroundThreshold.set("backgroundThreshold",15,1,300));
    gui.add(erodeFactor.set("erodeFactor",0,0,3));
    gui.add(dilateFactor.set("dilateFactor",0,0,3));
    gui.add(medianBlurFactor.set("medianBlur",1,0,5));
    gui.add(minContourArea.set("minContourArea",20, 5, 40));
    gui.add(maxContourArea.set("maxContourArea",(160*120)/3,40, 160*120)); // one third of the screen.
    gui.add(maxContours.set("maxContours", 5, 1, 10));
    ofSetFrameRate(fps);

    filename_save = "RPi_" + RPiId + "_params.json";

    if(ofFile::doesFileExist(filename_save)){
        ofLog(OF_LOG_NOTICE)<< "loading from file" + filename_save << endl;
        gui.loadFromFile(filename_save);
    }

    consoleListener.setup(this);
    consoleListener.startThread(false, false);

    background.setLearningTime(learningTime);
    background.setThresholdValue(backgroundThreshold);

    fps.addListener(this, &ofApp::fpsChanged);
    learningTime.addListener(this, &ofApp::learningTimeChanged);
    backgroundThreshold.addListener(this, &ofApp::backgroundThresholdChanged);

#ifdef __arm__
    cam.setup(160,120,false);//setup camera (w,h,color = true,gray = false);
    cam.setExposureMode(MMAL_PARAM_EXPOSUREMODE_FIXEDFPS);
    //cam.setExposureCompensation(0);
    //cam.setAWBMode(MMAL_PARAM_AWBMODE_OFF);
    //cam.setExposureCompensation(0);
#else
    cam.initGrabber(160,120);
#endif

    sender.setup("192.168.255.255", 8000);
    //sender.setup("127.0.0.1", 8000);
 	receiver.setup(OSC_PORT);
}

static int framenr = 1;

//--------------------------------------------------------------
void ofApp::update(){
    sent_blobs = 0;
	framenr++;
#ifdef __arm__
    frame = Mat(cam.grab());
    stringstream ss;
    ss << "rpi_" << RPiId << ".png";
    if(framenr % 100 == 0) {
      toOf(frame,tosave);

      ofSaveImage(tosave, ss.str());
    }
#else
    ofImage image;

    stringstream filename;
    filename << "images/"<< "file" << framenr << ".png";
    image.loadImage(filename.str());
    image.rotate90(2);
    frame = toCv(image);

#endif

    if (framenr == 130) {
        background.reset();
    }

    if (!frame.empty()) {

        //threshold( frame, frame, cutDown, 255,2 );

        background.update(frame, thresholded);
        thresholded.update();

        frameProcessed = toCv(thresholded);
        medianBlur ( frameProcessed, frameProcessed, medianBlurFactor );
        erode( frameProcessed, frameProcessed, erodeFactor );
        dilate( frameProcessed, frameProcessed, dilateFactor );

        ofPixels pix;
        ofImage img;
        toOf(frameProcessed, pix);
        grayImage.setFromPixels(pix);

        contourFinder.findContours(grayImage, minContourArea, maxContourArea, maxContours, true); // find holes

        ofxOscMessage numContours;
        stringstream addr;
        addr << "/RPi_" << RPiId << "/total_contours/";
        numContours.setAddress(addr.str());
        //numContours.addIntArg(contourFinder.nBlobs);
        //sender.sendMessage(numContours);

        for (int i = 0; i < contourFinder.nBlobs; i++){

            ofxOscMessage message;
            stringstream messageAddress;
            messageAddress << "/RPi_" << RPiId << "/contour_" << (i + 1) << "/";
            message.setAddress(messageAddress.str());
            float x = contourFinder.blobs[i].boundingRect.x;
            float y = contourFinder.blobs[i].boundingRect.y;
            float width = contourFinder.blobs[i].boundingRect.width;
            float height = contourFinder.blobs[i].boundingRect.height;

            //normalization
            x = x / 160;
            y = y / 120;
            width = width / 160;
            height = height / 120;

            //openGl standard
            x = x + width/2;
            y = y + height /2;
            x = x * 2 - 1;
            y = y * -2 + 1;
            width*=2;
            height*=2;

            if ( y - height/2 < 0 ) {
                message.addFloatArg(x);
                message.addFloatArg(y);
                message.addFloatArg(width);
                message.addFloatArg(height);

                sender.sendMessage(message);
                sent_blobs++;
            }

            //ofLog() << x << " and " << y;
        }

        numContours.addIntArg(sent_blobs);
		sender.sendMessage(numContours);

    }
	// hide old messages
	for(int i = 0; i < NUM_MSG_STRINGS; i++){
		if(timers[i] < ofGetElapsedTimef()){
			msg_strings[i] = "";
		}
	}

	// check for waiting messages
	while(receiver.hasWaitingMessages()){
		// get the next message
		ofxOscMessage rm;//receivedMessage
		ofxOscMessage sm;//sentMessage
		receiver.getNextMessage(&rm);
                //probably we need to move it out of the update
            if(rm.getAddress() == "/save"){

                gui.saveToFile(filename_save);
            }
            if(rm.getAddress() == "/getParams"){
                sm.setAddress("/allParams");
                sm.addStringArg(RPiId);
                sm.addIntArg(cutDown);
                sm.addIntArg(fps);
                sm.addIntArg(learningTime);
                sm.addIntArg(backgroundThreshold);
                sm.addIntArg(erodeFactor);
                sm.addIntArg(dilateFactor);
                sm.addIntArg(medianBlurFactor);
                sm.addIntArg(minContourArea);
                sm.addIntArg(maxContourArea);
                sm.addIntArg(maxContours);

                sender.sendMessage(sm);
            }
            else if(rm.getAddress() == "/whoIsThere"){
                sm.setAddress("/RPiId");
                sm.addStringArg(RPiId);
                sender.sendMessage(sm);
            }
            else if(rm.getAddress() == "/cutDown" + RPiId){
                cutDown = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/fps" + RPiId){
                fps = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/learningTime" + RPiId){
                learningTime = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/backgroundThreshold" + RPiId){
                backgroundThreshold = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/erodeFactor" + RPiId){
                erodeFactor = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/dilateFactor" + RPiId){
                dilateFactor = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/medianBlurFactor" + RPiId){
                medianBlurFactor = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/minContourArea" + RPiId){
                minContourArea = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/maxContourArea" + RPiId){
                maxContourArea = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/maxContours" + RPiId){
                maxContours = rm.getArgAsInt32(0);
            }
	    else if(rm.getAddress() == "/resetBG" + RPiId){
		background.reset();
	    }
	    else if(rm.getAddress() == "/loadFromFile" + RPiId){
		if(ofFile::doesFileExist(filename_save)){
		    ofLog(OF_LOG_NOTICE) << "loading from file " + filename_save << endl;
		    gui.loadFromFile(filename_save);
		}
		else{
		    ofLog(OF_LOG_NOTICE) << "file " + filename_save + " does not exist" << endl;
		}
	    }

	}
}

//-- Parameters events listeners

void ofApp::fpsChanged(int &fps) {
    ofSetFrameRate(fps);
}

void ofApp::learningTimeChanged(int &learningTime) {
    background.setLearningTime(learningTime);
}

void ofApp::backgroundThresholdChanged(int &backgroundThreshold) {
    background.setThresholdValue(backgroundThreshold);
}

//--------------------------------------------------------------
void ofApp::draw(){
//#ifdef __arm__
    drawMat(frame,0,0,320,240);
    drawMat(frameProcessed,0,240,320,240);
    thresholded.draw(320, 0,320,240);

    contourFinder.draw(320,240,320,240);

    gui.draw();
//#endif
}

//--------------------------------------------------------------
void ofApp::keyPressed  (int key){
    ofLogVerbose() << "keyPressed: " << key;

    if(key == ' ') {
        background.reset();
    }

    if(key == 'r') {
        framenr = 1;
        ofLog()<< "restarting video";
    }
}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){
    //thresh = ofMap(x,0,ofGetWidth(),0,255);
}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){

}
<commit_msg>adapted contour counting OSC<commit_after>#include "ofApp.h"
#include <opencv2/opencv.hpp>

using namespace ofxCv;
using namespace cv;

void ofApp::onCharacterReceived(SSHKeyListenerEventData& e)
{
	keyPressed((int)e.character);
}
//--------------------------------------------------------------
void ofApp::setup(){

    ofLog() << "RPid " << RPiId;
    gui.setup("panel");
    gui.setPosition(650,10);
    gui.add(cutDown.set( "cutDown", 110, 1, 255 ));
    gui.add(fps.set("fps", 16, 1, 30));
    gui.add(learningTime.set("learningTime",100,1,1000));
    gui.add(backgroundThreshold.set("backgroundThreshold",15,1,300));
    gui.add(erodeFactor.set("erodeFactor",0,0,3));
    gui.add(dilateFactor.set("dilateFactor",0,0,3));
    gui.add(medianBlurFactor.set("medianBlur",1,0,5));
    gui.add(minContourArea.set("minContourArea",20, 5, 40));
    gui.add(maxContourArea.set("maxContourArea",(160*120)/3,40, 160*120)); // one third of the screen.
    gui.add(maxContours.set("maxContours", 5, 1, 10));
    ofSetFrameRate(fps);

    filename_save = "RPi_" + RPiId + "_params.json";

    if(ofFile::doesFileExist(filename_save)){
        ofLog(OF_LOG_NOTICE)<< "loading from file" + filename_save << endl;
        gui.loadFromFile(filename_save);
    }

    consoleListener.setup(this);
    consoleListener.startThread(false, false);

    background.setLearningTime(learningTime);
    background.setThresholdValue(backgroundThreshold);

    fps.addListener(this, &ofApp::fpsChanged);
    learningTime.addListener(this, &ofApp::learningTimeChanged);
    backgroundThreshold.addListener(this, &ofApp::backgroundThresholdChanged);

#ifdef __arm__
    cam.setup(160,120,false);//setup camera (w,h,color = true,gray = false);
    cam.setExposureMode(MMAL_PARAM_EXPOSUREMODE_FIXEDFPS);
    //cam.setExposureCompensation(0);
    //cam.setAWBMode(MMAL_PARAM_AWBMODE_OFF);
    //cam.setExposureCompensation(0);
#else
    cam.initGrabber(160,120);
#endif

    sender.setup("192.168.255.255", 8000);
    //sender.setup("127.0.0.1", 8000);
 	receiver.setup(OSC_PORT);
}

static int framenr = 1;

//--------------------------------------------------------------
void ofApp::update(){
    sent_blobs = 0;
	framenr++;
#ifdef __arm__
    frame = Mat(cam.grab());
    stringstream ss;
    ss << "rpi_" << RPiId << ".png";
    if(framenr % 100 == 0) {
      toOf(frame,tosave);

      ofSaveImage(tosave, ss.str());
    }
#else
    ofImage image;

    stringstream filename;
    filename << "images/"<< "file" << framenr << ".png";
    image.loadImage(filename.str());
    image.rotate90(2);
    frame = toCv(image);

#endif

    if (framenr == 130) {
        background.reset();
    }

    if (!frame.empty()) {

        //threshold( frame, frame, cutDown, 255,2 );

        background.update(frame, thresholded);
        thresholded.update();

        frameProcessed = toCv(thresholded);
        medianBlur ( frameProcessed, frameProcessed, medianBlurFactor );
        erode( frameProcessed, frameProcessed, erodeFactor );
        dilate( frameProcessed, frameProcessed, dilateFactor );

        ofPixels pix;
        ofImage img;
        toOf(frameProcessed, pix);
        grayImage.setFromPixels(pix);

        contourFinder.findContours(grayImage, minContourArea, maxContourArea, maxContours, true); // find holes

        ofxOscMessage numContours;
        stringstream addr;
        addr << "/RPi_" << RPiId << "/total_contours/";
        numContours.setAddress(addr.str());
        //numContours.addIntArg(contourFinder.nBlobs);
        //sender.sendMessage(numContours);

        for (int i = 0; i < contourFinder.nBlobs; i++){

            ofxOscMessage message;
            stringstream messageAddress;
            float x = contourFinder.blobs[i].boundingRect.x;
            float y = contourFinder.blobs[i].boundingRect.y;
            float width = contourFinder.blobs[i].boundingRect.width;
            float height = contourFinder.blobs[i].boundingRect.height;

            //normalization
            x = x / 160;
            y = y / 120;
            width = width / 160;
            height = height / 120;

            //openGl standard
            x = x + width/2;
            y = y + height /2;
            x = x * 2 - 1;
            y = y * -2 + 1;
            width*=2;
            height*=2;

            if ( y - height/2 < 0 ) {
		message.addFloatArg(x);
                message.addFloatArg(y);
                message.addFloatArg(width);
                message.addFloatArg(height);

		messageAddress << "/RPi_" << RPiId << "/contour_" << (i + 1) << "/";
		message.setAddress(messageAddress.str());
                sender.sendMessage(message);
                sent_blobs++;
            }

            //ofLog() << x << " and " << y;
        }

        numContours.addIntArg(sent_blobs);
		sender.sendMessage(numContours);

    }
	// hide old messages
	for(int i = 0; i < NUM_MSG_STRINGS; i++){
		if(timers[i] < ofGetElapsedTimef()){
			msg_strings[i] = "";
		}
	}

	// check for waiting messages
	while(receiver.hasWaitingMessages()){
		// get the next message
		ofxOscMessage rm;//receivedMessage
		ofxOscMessage sm;//sentMessage
		receiver.getNextMessage(&rm);
                //probably we need to move it out of the update
            if(rm.getAddress() == "/save"){

                gui.saveToFile(filename_save);
            }
            if(rm.getAddress() == "/getParams"){
                sm.setAddress("/allParams");
                sm.addStringArg(RPiId);
                sm.addIntArg(cutDown);
                sm.addIntArg(fps);
                sm.addIntArg(learningTime);
                sm.addIntArg(backgroundThreshold);
                sm.addIntArg(erodeFactor);
                sm.addIntArg(dilateFactor);
                sm.addIntArg(medianBlurFactor);
                sm.addIntArg(minContourArea);
                sm.addIntArg(maxContourArea);
                sm.addIntArg(maxContours);

                sender.sendMessage(sm);
            }
            else if(rm.getAddress() == "/whoIsThere"){
                sm.setAddress("/RPiId");
                sm.addStringArg(RPiId);
                sender.sendMessage(sm);
            }
            else if(rm.getAddress() == "/cutDown" + RPiId){
                cutDown = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/fps" + RPiId){
                fps = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/learningTime" + RPiId){
                learningTime = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/backgroundThreshold" + RPiId){
                backgroundThreshold = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/erodeFactor" + RPiId){
                erodeFactor = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/dilateFactor" + RPiId){
                dilateFactor = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/medianBlurFactor" + RPiId){
                medianBlurFactor = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/minContourArea" + RPiId){
                minContourArea = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/maxContourArea" + RPiId){
                maxContourArea = rm.getArgAsInt32(0);
            }
            else if(rm.getAddress() == "/maxContours" + RPiId){
                maxContours = rm.getArgAsInt32(0);
            }
	    else if(rm.getAddress() == "/resetBG" + RPiId){
		background.reset();
	    }
	    else if(rm.getAddress() == "/loadFromFile" + RPiId){
		if(ofFile::doesFileExist(filename_save)){
		    ofLog(OF_LOG_NOTICE) << "loading from file " + filename_save << endl;
		    gui.loadFromFile(filename_save);
		}
		else{
		    ofLog(OF_LOG_NOTICE) << "file " + filename_save + " does not exist" << endl;
		}
	    }

	}
}

//-- Parameters events listeners

void ofApp::fpsChanged(int &fps) {
    ofSetFrameRate(fps);
}

void ofApp::learningTimeChanged(int &learningTime) {
    background.setLearningTime(learningTime);
}

void ofApp::backgroundThresholdChanged(int &backgroundThreshold) {
    background.setThresholdValue(backgroundThreshold);
}

//--------------------------------------------------------------
void ofApp::draw(){
//#ifdef __arm__
    drawMat(frame,0,0,320,240);
    drawMat(frameProcessed,0,240,320,240);
    thresholded.draw(320, 0,320,240);

    contourFinder.draw(320,240,320,240);

    gui.draw();
//#endif
}

//--------------------------------------------------------------
void ofApp::keyPressed  (int key){
    ofLogVerbose() << "keyPressed: " << key;

    if(key == ' ') {
        background.reset();
    }

    if(key == 'r') {
        framenr = 1;
        ofLog()<< "restarting video";
    }
}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){
    //thresh = ofMap(x,0,ofGetWidth(),0,255);
}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){

}
<|endoftext|>


<commit_before>#include "Synthesis.h"
#include "IPlug_include_in_plug_src.h"
#include "IControl.h"
#include "IKeyboardControl.h"
#include "ADSRVisualizationControl.h"
#include "resource.h"

const int kNumPrograms = 5;

enum EAdsr
{
	E_Att = 0,
	E_Dec,
	E_Sus,
	E_Rel,
};

enum EParams
{
	mWaveform = 0,
	mAttack,
	mDecay,
	mSustain,
	mRelease,
	mFilterMode,
	mFilterCutoff,
	mFilterResonance,
	mFilterAttack,
	mFilterDecay,
	mFilterSustain,
	mFilterRelease,
	mFilterEnvelopeAmount,
	kNumParams
};

enum ELayout
{
	kWidth = GUI_WIDTH,
	kHeight = GUI_HEIGHT,
	kKeybX = 12,
	kKeybY = 154
};

Synthesis::Synthesis(IPlugInstanceInfo instanceInfo)
	: IPLUG_CTOR(kNumParams, kNumPrograms, instanceInfo),
	lastVirtualKeyboardNoteNumber(virtualKeyboardMinimumNoteNumber - 1),
	filterEnvelopeAmount(0.0) {

	TRACE;

	IGraphics* pGraphics = MakeGraphics(this, kWidth, kHeight);
	pGraphics->AttachBackground(BG_ID, BG_FN);

	IBitmap pianoKeyImage = pGraphics->LoadIBitmap(PIANO_KEY_ID, PIANO_KEY_FN);

	//                            C#     D#          F#      G#      A#
	int keyCoordinates[12] = { 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55 };
	mVirtualKeyboard = new IKeyboardControl(this, kKeybX, kKeybY, virtualKeyboardMinimumNoteNumber, /* octaves: */ 10, &pianoKeyImage, &pianoKeyImage, keyCoordinates);

	pGraphics->AttachControl(mVirtualKeyboard);

	// Waveform switch
	GetParam(mWaveform)->InitEnum("Waveform", OSCILLATOR_MODE_SINE, kNumOscillatorModes);
	GetParam(mWaveform)->SetDisplayText(0, "Sine"); // Needed for VST3, thanks plunntic
	IBitmap waveformBitmap = pGraphics->LoadIBitmap(WAVEFORM_ID, WAVEFORM_FN, 4);
	pGraphics->AttachControl(new ISwitchControl(this, 42, 20, mWaveform, &waveformBitmap));

	// Knob bitmap for ADSR
	IBitmap greenKnobBitmap = pGraphics->LoadIBitmap(GREEN_KNOB_ID, GREEN_KNOB_FN, 31);
	IBitmap blueKnobBitmap = pGraphics->LoadIBitmap(BLUE_KNOB_ID, BLUE_KNOB_FN, 31);
	IBitmap blueKnobCenterBitmap = pGraphics->LoadIBitmap(BLUE_KNOB_CENTER_ID, BLUE_KNOB_CENTER_FN, 31);

	// Attack knob:
	ampAdsrKnobs[E_Att] = new IKnobMultiControl(this, 329, 10, mAttack, &greenKnobBitmap);
	GetParam(mAttack)->InitDouble("Attack", 0.01, 0.01, 10.0, 0.001);
	GetParam(mAttack)->SetShape(3);
	pGraphics->AttachControl(ampAdsrKnobs[E_Att]);
	// Decay knob:
	ampAdsrKnobs[E_Dec] = new IKnobMultiControl(this, 383, 10, mDecay, &greenKnobBitmap);
	GetParam(mDecay)->InitDouble("Decay", 0.5, 0.01, 15.0, 0.001);
	GetParam(mDecay)->SetShape(3);
	pGraphics->AttachControl(ampAdsrKnobs[E_Dec]);
	// Sustain knob:
	ampAdsrKnobs[E_Sus] = new IKnobMultiControl(this, 437, 10, mSustain, &greenKnobBitmap);
	GetParam(mSustain)->InitDouble("Sustain", 0.1, 0.001, 1.0, 0.001);
	GetParam(mSustain)->SetShape(2);
	pGraphics->AttachControl(ampAdsrKnobs[E_Sus]);
	// Release knob:
	ampAdsrKnobs[E_Rel] = new IKnobMultiControl(this, 491, 10, mRelease, &greenKnobBitmap);
	GetParam(mRelease)->InitDouble("Release", 1.0, 0.001, 15.0, 0.001);
	GetParam(mRelease)->SetShape(3);
	pGraphics->AttachControl(ampAdsrKnobs[E_Rel]);

	// ADSR Visualization
	ampAdsrVisualization = new ADSRVisualizationControl(this, IRECT(546, 15, 648, 63));
	pGraphics->AttachControl(ampAdsrVisualization);

	// Filter switch
	GetParam(mWaveform)->InitEnum("Filter Mode", Filter::FILTER_MODE_LOWPASS, Filter::kNumFilterModes);
	GetParam(mWaveform)->SetDisplayText(0, "LP"); // Needed for VST3, thanks plunntic
	IBitmap filtermodeBitmap = pGraphics->LoadIBitmap(FILTERMODE_ID, FILTERMODE_FN, 3);
	pGraphics->AttachControl(new ISwitchControl(this, 42, 95, mFilterMode, &filtermodeBitmap));

	// Filter options
	// Cutoff knob:
	GetParam(mFilterCutoff)->InitDouble("Cutoff", 0.99, 0.01, 0.99, 0.001);
	GetParam(mFilterCutoff)->SetShape(2);
	pGraphics->AttachControl(new IKnobMultiControl(this, 137, 82, mFilterCutoff, &blueKnobBitmap));
	// Resonance knob:
	GetParam(mFilterResonance)->InitDouble("Resonance", 0.01, 0.01, 1.0, 0.001);
	pGraphics->AttachControl(new IKnobMultiControl(this, 195, 82, mFilterResonance, &blueKnobBitmap));
	// Filter envelope amount knob:
	GetParam(mFilterEnvelopeAmount)->InitDouble("Filter Env Amount", 0.0, -1.0, 1.0, 0.001);
	pGraphics->AttachControl(new IKnobMultiControl(this, 255, 82, mFilterEnvelopeAmount, &blueKnobCenterBitmap));

	// Attack knob:
	filterAdsrKnobs[E_Att] = new IKnobMultiControl(this, 329, 82, mFilterAttack, &blueKnobBitmap);
	GetParam(mFilterAttack)->InitDouble("Filter Env Attack", 0.01, 0.01, 10.0, 0.001);
	GetParam(mFilterAttack)->SetShape(3);
	pGraphics->AttachControl(filterAdsrKnobs[E_Att]);
	// Decay knob:
	filterAdsrKnobs[E_Dec] = new IKnobMultiControl(this, 383, 82, mFilterDecay, &blueKnobBitmap);
	GetParam(mFilterDecay)->InitDouble("Filter Env Decay", 0.5, 0.01, 15.0, 0.001);
	GetParam(mFilterDecay)->SetShape(3);
	pGraphics->AttachControl(filterAdsrKnobs[E_Dec]);
	// Sustain knob:
	filterAdsrKnobs[E_Sus] = new IKnobMultiControl(this, 437, 82, mFilterSustain, &blueKnobBitmap);
	GetParam(mFilterSustain)->InitDouble("Filter Env Sustain", 0.1, 0.001, 1.0, 0.001);
	GetParam(mFilterSustain)->SetShape(2);
	pGraphics->AttachControl(filterAdsrKnobs[E_Sus]);
	// Release knob:
	filterAdsrKnobs[E_Rel] = new IKnobMultiControl(this, 491, 82, mFilterRelease, &blueKnobBitmap);
	GetParam(mFilterRelease)->InitDouble("Filter Env Release", 1.0, 0.001, 15.0, 0.001);
	GetParam(mFilterRelease)->SetShape(3);
	pGraphics->AttachControl(filterAdsrKnobs[E_Rel]);

	// Filter ADSR Visualization
	filterEnvAdsrVisualization = new ADSRVisualizationControl(this, IRECT(546, 87, 648, 135));
	pGraphics->AttachControl(filterEnvAdsrVisualization);

	AttachGraphics(pGraphics);

	CreatePresets();

	mMIDIReceiver.noteOn.Connect(this, &Synthesis::onNoteOn);
	mMIDIReceiver.noteOff.Connect(this, &Synthesis::onNoteOff);
	mEnvelopeGenerator.beganEnvelopeCycle.Connect(this, &Synthesis::onBeganEnvelopeCycle);
	mEnvelopeGenerator.finishedEnvelopeCycle.Connect(this, &Synthesis::onFinishedEnvelopeCycle);
}

Synthesis::~Synthesis() {}

void Synthesis::ProcessDoubleReplacing(double** inputs, double** outputs, int nFrames)
{
	// Mutex is already locked for us.

	double *leftOutput = outputs[0];
	double *rightOutput = outputs[1];

	processVirtualKeyboard();
	for (int i = 0; i < nFrames; ++i) {
		mMIDIReceiver.advance();
		int velocity = mMIDIReceiver.getLastVelocity();
		mOscillator.setFrequency(mMIDIReceiver.getLastFrequency());
		mFilter.setCutoffMod(mFilterEnvelopeGenerator.nextSample() * filterEnvelopeAmount);
		//leftOutput[i] = rightOutput[i] = mOscillator.nextSample() * mEnvelopeGenerator.nextSample() * velocity / 127.0;
		leftOutput[i] = rightOutput[i] = mFilter.process(mOscillator.nextSample() * mEnvelopeGenerator.nextSample() * velocity / 127.0);
	}

	mMIDIReceiver.Flush(nFrames);
}

void Synthesis::CreatePresets()
{
}

void Synthesis::Reset()
{
	TRACE;
	IMutexLock lock(this);
	mOscillator.setSampleRate(GetSampleRate());
	mEnvelopeGenerator.setSampleRate(GetSampleRate());
	mFilterEnvelopeGenerator.setSampleRate(GetSampleRate());
}

void Synthesis::OnParamChange(int paramIdx)
{
	IMutexLock lock(this);
	switch (paramIdx) {
	case mWaveform:
		mOscillator.setMode(static_cast<OscillatorMode>(GetParam(mWaveform)->Int()));
		break;
	case mAttack:
	case mDecay:
	case mSustain:
	case mRelease:
		mEnvelopeGenerator.setStageValue(static_cast<EnvelopeGenerator::EnvelopeStage>(paramIdx), GetParam(paramIdx)->Value());
		ampAdsrVisualization->setADSR(ampAdsrKnobs[E_Att]->GetValue(), ampAdsrKnobs[E_Dec]->GetValue(),
			ampAdsrKnobs[E_Sus]->GetValue(), ampAdsrKnobs[E_Rel]->GetValue());
		//ampAdsrVisualization->setADSR(ampAdsrKnobs[E_Att]->GetValue, ampAdsrKnobs[E_Dec]->GetValue, ampAdsrKnobs[E_Sus]->GetValue, ampAdsrKnobs[E_Rel]->GetValue);
		break;
	case mFilterCutoff:
		mFilter.setCutoff(GetParam(paramIdx)->Value());
		break;
	case mFilterResonance:
		mFilter.setResonance(GetParam(paramIdx)->Value());
		break;
	case mFilterMode:
		mFilter.setFilterMode(static_cast<Filter::FilterMode>(GetParam(paramIdx)->Int()));
		break;
	case mFilterAttack:
		mFilterEnvelopeGenerator.setStageValue(EnvelopeGenerator::ENVELOPE_STAGE_ATTACK, GetParam(paramIdx)->Value());
		filterEnvAdsrVisualization->setADSR(filterAdsrKnobs[E_Att]->GetValue(), filterAdsrKnobs[E_Dec]->GetValue(),
			filterAdsrKnobs[E_Sus]->GetValue(), filterAdsrKnobs[E_Rel]->GetValue());
		break;
	case mFilterDecay:
		mFilterEnvelopeGenerator.setStageValue(EnvelopeGenerator::ENVELOPE_STAGE_DECAY, GetParam(paramIdx)->Value());
		filterEnvAdsrVisualization->setADSR(filterAdsrKnobs[E_Att]->GetValue(), filterAdsrKnobs[E_Dec]->GetValue(),
			filterAdsrKnobs[E_Sus]->GetValue(), filterAdsrKnobs[E_Rel]->GetValue());
		break;
	case mFilterSustain:
		mFilterEnvelopeGenerator.setStageValue(EnvelopeGenerator::ENVELOPE_STAGE_SUSTAIN, GetParam(paramIdx)->Value());
		filterEnvAdsrVisualization->setADSR(filterAdsrKnobs[E_Att]->GetValue(), filterAdsrKnobs[E_Dec]->GetValue(),
			filterAdsrKnobs[E_Sus]->GetValue(), filterAdsrKnobs[E_Rel]->GetValue());
		break;
	case mFilterRelease:
		mFilterEnvelopeGenerator.setStageValue(EnvelopeGenerator::ENVELOPE_STAGE_RELEASE, GetParam(paramIdx)->Value());
		filterEnvAdsrVisualization->setADSR(filterAdsrKnobs[E_Att]->GetValue(), filterAdsrKnobs[E_Dec]->GetValue(),
			filterAdsrKnobs[E_Sus]->GetValue(), filterAdsrKnobs[E_Rel]->GetValue());
		break;
	case mFilterEnvelopeAmount:
		filterEnvelopeAmount = GetParam(paramIdx)->Value();
		break;
	}
}

void Synthesis::ProcessMidiMsg(IMidiMsg* pMsg) {
	mMIDIReceiver.onMessageReceived(pMsg);
	mVirtualKeyboard->SetDirty();
}

void Synthesis::processVirtualKeyboard() {
	IKeyboardControl* virtualKeyboard = (IKeyboardControl*)mVirtualKeyboard;
	int virtualKeyboardNoteNumber = virtualKeyboard->GetKey() + virtualKeyboardMinimumNoteNumber;

	if (lastVirtualKeyboardNoteNumber >= virtualKeyboardMinimumNoteNumber && virtualKeyboardNoteNumber != lastVirtualKeyboardNoteNumber) {
		// The note number has changed from a valid key to something else (valid key or nothing). Release the valid key:
		IMidiMsg midiMessage;
		midiMessage.MakeNoteOffMsg(lastVirtualKeyboardNoteNumber, 0);
		mMIDIReceiver.onMessageReceived(&midiMessage);
	}

	if (virtualKeyboardNoteNumber >= virtualKeyboardMinimumNoteNumber && virtualKeyboardNoteNumber != lastVirtualKeyboardNoteNumber) {
		// A valid key is pressed that wasn't pressed the previous call. Send a "note on" message to the MIDI receiver:
		IMidiMsg midiMessage;
		midiMessage.MakeNoteOnMsg(virtualKeyboardNoteNumber, virtualKeyboard->GetVelocity(), 0);
		mMIDIReceiver.onMessageReceived(&midiMessage);
	}

	lastVirtualKeyboardNoteNumber = virtualKeyboardNoteNumber;
}<commit_msg>Mistake.. hotfix<commit_after>#include "Synthesis.h"
#include "IPlug_include_in_plug_src.h"
#include "IControl.h"
#include "IKeyboardControl.h"
#include "ADSRVisualizationControl.h"
#include "resource.h"

const int kNumPrograms = 5;

enum EAdsr
{
	E_Att = 0,
	E_Dec,
	E_Sus,
	E_Rel,
};

enum EParams
{
	mWaveform = 0,
	mAttack,
	mDecay,
	mSustain,
	mRelease,
	mFilterMode,
	mFilterCutoff,
	mFilterResonance,
	mFilterAttack,
	mFilterDecay,
	mFilterSustain,
	mFilterRelease,
	mFilterEnvelopeAmount,
	kNumParams
};

enum ELayout
{
	kWidth = GUI_WIDTH,
	kHeight = GUI_HEIGHT,
	kKeybX = 12,
	kKeybY = 154
};

Synthesis::Synthesis(IPlugInstanceInfo instanceInfo)
	: IPLUG_CTOR(kNumParams, kNumPrograms, instanceInfo),
	lastVirtualKeyboardNoteNumber(virtualKeyboardMinimumNoteNumber - 1),
	filterEnvelopeAmount(0.0) {

	TRACE;

	IGraphics* pGraphics = MakeGraphics(this, kWidth, kHeight);
	pGraphics->AttachBackground(BG_ID, BG_FN);

	IBitmap pianoKeyImage = pGraphics->LoadIBitmap(PIANO_KEY_ID, PIANO_KEY_FN);

	//                            C#     D#          F#      G#      A#
	int keyCoordinates[12] = { 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55 };
	mVirtualKeyboard = new IKeyboardControl(this, kKeybX, kKeybY, virtualKeyboardMinimumNoteNumber, /* octaves: */ 10, &pianoKeyImage, &pianoKeyImage, keyCoordinates);

	pGraphics->AttachControl(mVirtualKeyboard);

	// Waveform switch
	GetParam(mWaveform)->InitEnum("Waveform", OSCILLATOR_MODE_SINE, kNumOscillatorModes);
	GetParam(mWaveform)->SetDisplayText(0, "Sine"); // Needed for VST3, thanks plunntic
	IBitmap waveformBitmap = pGraphics->LoadIBitmap(WAVEFORM_ID, WAVEFORM_FN, 4);
	pGraphics->AttachControl(new ISwitchControl(this, 42, 20, mWaveform, &waveformBitmap));

	// Knob bitmap for ADSR
	IBitmap greenKnobBitmap = pGraphics->LoadIBitmap(GREEN_KNOB_ID, GREEN_KNOB_FN, 31);
	IBitmap blueKnobBitmap = pGraphics->LoadIBitmap(BLUE_KNOB_ID, BLUE_KNOB_FN, 31);
	IBitmap blueKnobCenterBitmap = pGraphics->LoadIBitmap(BLUE_KNOB_CENTER_ID, BLUE_KNOB_CENTER_FN, 31);

	// Attack knob:
	ampAdsrKnobs[E_Att] = new IKnobMultiControl(this, 329, 10, mAttack, &greenKnobBitmap);
	GetParam(mAttack)->InitDouble("Attack", 0.01, 0.01, 10.0, 0.001);
	GetParam(mAttack)->SetShape(3);
	pGraphics->AttachControl(ampAdsrKnobs[E_Att]);
	// Decay knob:
	ampAdsrKnobs[E_Dec] = new IKnobMultiControl(this, 383, 10, mDecay, &greenKnobBitmap);
	GetParam(mDecay)->InitDouble("Decay", 0.5, 0.01, 15.0, 0.001);
	GetParam(mDecay)->SetShape(3);
	pGraphics->AttachControl(ampAdsrKnobs[E_Dec]);
	// Sustain knob:
	ampAdsrKnobs[E_Sus] = new IKnobMultiControl(this, 437, 10, mSustain, &greenKnobBitmap);
	GetParam(mSustain)->InitDouble("Sustain", 0.1, 0.001, 1.0, 0.001);
	GetParam(mSustain)->SetShape(2);
	pGraphics->AttachControl(ampAdsrKnobs[E_Sus]);
	// Release knob:
	ampAdsrKnobs[E_Rel] = new IKnobMultiControl(this, 491, 10, mRelease, &greenKnobBitmap);
	GetParam(mRelease)->InitDouble("Release", 1.0, 0.001, 15.0, 0.001);
	GetParam(mRelease)->SetShape(3);
	pGraphics->AttachControl(ampAdsrKnobs[E_Rel]);

	// ADSR Visualization
	ampAdsrVisualization = new ADSRVisualizationControl(this, IRECT(546, 15, 648, 63));
	pGraphics->AttachControl(ampAdsrVisualization);

	// Filter switch
	GetParam(mFilterMode)->InitEnum("Filter Mode", Filter::FILTER_MODE_LOWPASS, Filter::kNumFilterModes);
	GetParam(mFilterMode)->SetDisplayText(0, "LP"); // Needed for VST3, thanks plunntic
	IBitmap filtermodeBitmap = pGraphics->LoadIBitmap(FILTERMODE_ID, FILTERMODE_FN, 3);
	pGraphics->AttachControl(new ISwitchControl(this, 42, 95, mFilterMode, &filtermodeBitmap));

	// Filter options
	// Cutoff knob:
	GetParam(mFilterCutoff)->InitDouble("Cutoff", 0.99, 0.01, 0.99, 0.001);
	GetParam(mFilterCutoff)->SetShape(2);
	pGraphics->AttachControl(new IKnobMultiControl(this, 137, 82, mFilterCutoff, &blueKnobBitmap));
	// Resonance knob:
	GetParam(mFilterResonance)->InitDouble("Resonance", 0.01, 0.01, 1.0, 0.001);
	pGraphics->AttachControl(new IKnobMultiControl(this, 195, 82, mFilterResonance, &blueKnobBitmap));
	// Filter envelope amount knob:
	GetParam(mFilterEnvelopeAmount)->InitDouble("Filter Env Amount", 0.0, -1.0, 1.0, 0.001);
	pGraphics->AttachControl(new IKnobMultiControl(this, 255, 82, mFilterEnvelopeAmount, &blueKnobCenterBitmap));

	// Attack knob:
	filterAdsrKnobs[E_Att] = new IKnobMultiControl(this, 329, 82, mFilterAttack, &blueKnobBitmap);
	GetParam(mFilterAttack)->InitDouble("Filter Env Attack", 0.01, 0.01, 10.0, 0.001);
	GetParam(mFilterAttack)->SetShape(3);
	pGraphics->AttachControl(filterAdsrKnobs[E_Att]);
	// Decay knob:
	filterAdsrKnobs[E_Dec] = new IKnobMultiControl(this, 383, 82, mFilterDecay, &blueKnobBitmap);
	GetParam(mFilterDecay)->InitDouble("Filter Env Decay", 0.5, 0.01, 15.0, 0.001);
	GetParam(mFilterDecay)->SetShape(3);
	pGraphics->AttachControl(filterAdsrKnobs[E_Dec]);
	// Sustain knob:
	filterAdsrKnobs[E_Sus] = new IKnobMultiControl(this, 437, 82, mFilterSustain, &blueKnobBitmap);
	GetParam(mFilterSustain)->InitDouble("Filter Env Sustain", 0.1, 0.001, 1.0, 0.001);
	GetParam(mFilterSustain)->SetShape(2);
	pGraphics->AttachControl(filterAdsrKnobs[E_Sus]);
	// Release knob:
	filterAdsrKnobs[E_Rel] = new IKnobMultiControl(this, 491, 82, mFilterRelease, &blueKnobBitmap);
	GetParam(mFilterRelease)->InitDouble("Filter Env Release", 1.0, 0.001, 15.0, 0.001);
	GetParam(mFilterRelease)->SetShape(3);
	pGraphics->AttachControl(filterAdsrKnobs[E_Rel]);

	// Filter ADSR Visualization
	filterEnvAdsrVisualization = new ADSRVisualizationControl(this, IRECT(546, 87, 648, 135));
	pGraphics->AttachControl(filterEnvAdsrVisualization);

	AttachGraphics(pGraphics);

	CreatePresets();

	mMIDIReceiver.noteOn.Connect(this, &Synthesis::onNoteOn);
	mMIDIReceiver.noteOff.Connect(this, &Synthesis::onNoteOff);
	mEnvelopeGenerator.beganEnvelopeCycle.Connect(this, &Synthesis::onBeganEnvelopeCycle);
	mEnvelopeGenerator.finishedEnvelopeCycle.Connect(this, &Synthesis::onFinishedEnvelopeCycle);
}

Synthesis::~Synthesis() {}

void Synthesis::ProcessDoubleReplacing(double** inputs, double** outputs, int nFrames)
{
	// Mutex is already locked for us.

	double *leftOutput = outputs[0];
	double *rightOutput = outputs[1];

	processVirtualKeyboard();
	for (int i = 0; i < nFrames; ++i) {
		mMIDIReceiver.advance();
		int velocity = mMIDIReceiver.getLastVelocity();
		mOscillator.setFrequency(mMIDIReceiver.getLastFrequency());
		mFilter.setCutoffMod(mFilterEnvelopeGenerator.nextSample() * filterEnvelopeAmount);
		//leftOutput[i] = rightOutput[i] = mOscillator.nextSample() * mEnvelopeGenerator.nextSample() * velocity / 127.0;
		leftOutput[i] = rightOutput[i] = mFilter.process(mOscillator.nextSample() * mEnvelopeGenerator.nextSample() * velocity / 127.0);
	}

	mMIDIReceiver.Flush(nFrames);
}

void Synthesis::CreatePresets()
{
}

void Synthesis::Reset()
{
	TRACE;
	IMutexLock lock(this);
	mOscillator.setSampleRate(GetSampleRate());
	mEnvelopeGenerator.setSampleRate(GetSampleRate());
	mFilterEnvelopeGenerator.setSampleRate(GetSampleRate());
}

void Synthesis::OnParamChange(int paramIdx)
{
	IMutexLock lock(this);
	switch (paramIdx) {
	case mWaveform:
		mOscillator.setMode(static_cast<OscillatorMode>(GetParam(mWaveform)->Int()));
		break;
	case mAttack:
	case mDecay:
	case mSustain:
	case mRelease:
		mEnvelopeGenerator.setStageValue(static_cast<EnvelopeGenerator::EnvelopeStage>(paramIdx), GetParam(paramIdx)->Value());
		ampAdsrVisualization->setADSR(ampAdsrKnobs[E_Att]->GetValue(), ampAdsrKnobs[E_Dec]->GetValue(),
			ampAdsrKnobs[E_Sus]->GetValue(), ampAdsrKnobs[E_Rel]->GetValue());
		//ampAdsrVisualization->setADSR(ampAdsrKnobs[E_Att]->GetValue, ampAdsrKnobs[E_Dec]->GetValue, ampAdsrKnobs[E_Sus]->GetValue, ampAdsrKnobs[E_Rel]->GetValue);
		break;
	case mFilterCutoff:
		mFilter.setCutoff(GetParam(paramIdx)->Value());
		break;
	case mFilterResonance:
		mFilter.setResonance(GetParam(paramIdx)->Value());
		break;
	case mFilterMode:
		mFilter.setFilterMode(static_cast<Filter::FilterMode>(GetParam(paramIdx)->Int()));
		break;
	case mFilterAttack:
		mFilterEnvelopeGenerator.setStageValue(EnvelopeGenerator::ENVELOPE_STAGE_ATTACK, GetParam(paramIdx)->Value());
		filterEnvAdsrVisualization->setADSR(filterAdsrKnobs[E_Att]->GetValue(), filterAdsrKnobs[E_Dec]->GetValue(),
			filterAdsrKnobs[E_Sus]->GetValue(), filterAdsrKnobs[E_Rel]->GetValue());
		break;
	case mFilterDecay:
		mFilterEnvelopeGenerator.setStageValue(EnvelopeGenerator::ENVELOPE_STAGE_DECAY, GetParam(paramIdx)->Value());
		filterEnvAdsrVisualization->setADSR(filterAdsrKnobs[E_Att]->GetValue(), filterAdsrKnobs[E_Dec]->GetValue(),
			filterAdsrKnobs[E_Sus]->GetValue(), filterAdsrKnobs[E_Rel]->GetValue());
		break;
	case mFilterSustain:
		mFilterEnvelopeGenerator.setStageValue(EnvelopeGenerator::ENVELOPE_STAGE_SUSTAIN, GetParam(paramIdx)->Value());
		filterEnvAdsrVisualization->setADSR(filterAdsrKnobs[E_Att]->GetValue(), filterAdsrKnobs[E_Dec]->GetValue(),
			filterAdsrKnobs[E_Sus]->GetValue(), filterAdsrKnobs[E_Rel]->GetValue());
		break;
	case mFilterRelease:
		mFilterEnvelopeGenerator.setStageValue(EnvelopeGenerator::ENVELOPE_STAGE_RELEASE, GetParam(paramIdx)->Value());
		filterEnvAdsrVisualization->setADSR(filterAdsrKnobs[E_Att]->GetValue(), filterAdsrKnobs[E_Dec]->GetValue(),
			filterAdsrKnobs[E_Sus]->GetValue(), filterAdsrKnobs[E_Rel]->GetValue());
		break;
	case mFilterEnvelopeAmount:
		filterEnvelopeAmount = GetParam(paramIdx)->Value();
		break;
	}
}

void Synthesis::ProcessMidiMsg(IMidiMsg* pMsg) {
	mMIDIReceiver.onMessageReceived(pMsg);
	mVirtualKeyboard->SetDirty();
}

void Synthesis::processVirtualKeyboard() {
	IKeyboardControl* virtualKeyboard = (IKeyboardControl*)mVirtualKeyboard;
	int virtualKeyboardNoteNumber = virtualKeyboard->GetKey() + virtualKeyboardMinimumNoteNumber;

	if (lastVirtualKeyboardNoteNumber >= virtualKeyboardMinimumNoteNumber && virtualKeyboardNoteNumber != lastVirtualKeyboardNoteNumber) {
		// The note number has changed from a valid key to something else (valid key or nothing). Release the valid key:
		IMidiMsg midiMessage;
		midiMessage.MakeNoteOffMsg(lastVirtualKeyboardNoteNumber, 0);
		mMIDIReceiver.onMessageReceived(&midiMessage);
	}

	if (virtualKeyboardNoteNumber >= virtualKeyboardMinimumNoteNumber && virtualKeyboardNoteNumber != lastVirtualKeyboardNoteNumber) {
		// A valid key is pressed that wasn't pressed the previous call. Send a "note on" message to the MIDI receiver:
		IMidiMsg midiMessage;
		midiMessage.MakeNoteOnMsg(virtualKeyboardNoteNumber, virtualKeyboard->GetVelocity(), 0);
		mMIDIReceiver.onMessageReceived(&midiMessage);
	}

	lastVirtualKeyboardNoteNumber = virtualKeyboardNoteNumber;
}<|endoftext|>


<commit_before>#include "widgets/WidgetParticleList.h"

#include "ParticleUniverseSystemManager.h"

#include <QFileDialog>

namespace i6engine {
namespace particleEditor {
namespace widgets {

	WidgetParticleList::WidgetParticleList(QWidget * par) : QWidget(par), _currentParticleTemplate(), _templateMap(), _system(nullptr), _dirty(false), _script() {
		setupUi(this);

		refreshParticleList();

		connect(treeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(selectParticle(QTreeWidgetItem *)));
	}

	WidgetParticleList::~WidgetParticleList() {
	}

	void WidgetParticleList::selectParticle(QTreeWidgetItem * item) {
		if (_currentParticleTemplate != item->text(0)) {
			if (_dirty && _script.toStdString() != ParticleUniverse::ParticleSystemManager::getSingleton().writeScript(_system)) {
				QString file = QFileDialog::getSaveFileName(nullptr, "Save file ...", QString::fromStdString("../media/particles"), "Particle Files (*.pu)");
				if (!file.isEmpty()) {
					ParticleUniverse::ParticleSystemManager::getSingleton().writeScript(_system, file.toStdString());
				}
			}
			_currentParticleTemplate = item->text(0);
			_dirty = false;
			emit createNewSystem(item->text(0));
		}
	}

	void WidgetParticleList::selectParticle(QString templateName) {
		selectParticle(_templateMap[templateName]);
	}

	void WidgetParticleList::setNewParticleSystem(ParticleUniverse::ParticleSystem * system) {
		_system = system;
		_script = QString::fromStdString(ParticleUniverse::ParticleSystemManager::getSingleton().writeScript(_system));
	}

	void WidgetParticleList::notifyChanged() {
		_dirty = true;
	}

	void WidgetParticleList::saveParticle() {
		if (_dirty && _script.toStdString() != ParticleUniverse::ParticleSystemManager::getSingleton().writeScript(_system)) {
			QString file = QFileDialog::getSaveFileName(nullptr, "Save file ...", QString::fromStdString("../media/particles"), "Particle Files (*.pu)");
			if (!file.isEmpty()) {
				ParticleUniverse::ParticleSystemManager::getSingleton().writeScript(_system, file.toStdString());
			}
			_dirty = false;
		}
	}

	void WidgetParticleList::refreshParticleList() {
		_currentParticleTemplate = "";
		_templateMap.clear();
		ParticleUniverse::vector<ParticleUniverse::String> names;
		ParticleUniverse::ParticleSystemManager::getSingletonPtr()->particleSystemTemplateNames(names);
		treeWidget->clear();
		for (ParticleUniverse::String s : names) {
			QTreeWidgetItem * twi = new QTreeWidgetItem(treeWidget, { QString::fromStdString(s) });
			_templateMap.insert(std::make_pair(QString::fromStdString(s), twi));
		}
	}

} /* namespace widgets */
} /* namespace particleEditor */
} /* namespace i6engine */
<commit_msg>ISIXE-1712 saving a renamend particle should work now<commit_after>#include "widgets/WidgetParticleList.h"

#include "ParticleUniverseSystemManager.h"

#include <QFileDialog>

namespace i6engine {
namespace particleEditor {
namespace widgets {

	WidgetParticleList::WidgetParticleList(QWidget * par) : QWidget(par), _currentParticleTemplate(), _templateMap(), _system(nullptr), _dirty(false), _script() {
		setupUi(this);

		refreshParticleList();

		connect(treeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(selectParticle(QTreeWidgetItem *)));
	}

	WidgetParticleList::~WidgetParticleList() {
	}

	void WidgetParticleList::selectParticle(QTreeWidgetItem * item) {
		if (_currentParticleTemplate != item->text(0)) {
			if (_dirty && _script.toStdString() != ParticleUniverse::ParticleSystemManager::getSingleton().writeScript(_system)) {
				QString file = QFileDialog::getSaveFileName(nullptr, "Save file ...", QString::fromStdString("../media/particles"), "Particle Files (*.pu)");
				if (!file.isEmpty()) {
					ParticleUniverse::ParticleSystemManager::getSingleton().writeScript(_system, file.toStdString());
				}
			}
			_currentParticleTemplate = item->text(0);
			_dirty = false;
			emit createNewSystem(item->text(0));
		}
	}

	void WidgetParticleList::selectParticle(QString templateName) {
		selectParticle(_templateMap[templateName]);
	}

	void WidgetParticleList::setNewParticleSystem(ParticleUniverse::ParticleSystem * system) {
		_system = system;
		_script = QString::fromStdString(ParticleUniverse::ParticleSystemManager::getSingleton().writeScript(_system));
	}

	void WidgetParticleList::notifyChanged() {
		_dirty = true;
	}

	void WidgetParticleList::saveParticle() {
		if (_dirty) {
			QString file = QFileDialog::getSaveFileName(nullptr, "Save file ...", QString::fromStdString("../media/particles"), "Particle Files (*.pu)");
			if (!file.isEmpty()) {
				ParticleUniverse::ParticleSystemManager::getSingleton().writeScript(_system, file.toStdString());
			}
			_dirty = false;
		}
	}

	void WidgetParticleList::refreshParticleList() {
		_currentParticleTemplate = "";
		_templateMap.clear();
		ParticleUniverse::vector<ParticleUniverse::String> names;
		ParticleUniverse::ParticleSystemManager::getSingletonPtr()->particleSystemTemplateNames(names);
		treeWidget->clear();
		for (ParticleUniverse::String s : names) {
			QTreeWidgetItem * twi = new QTreeWidgetItem(treeWidget, { QString::fromStdString(s) });
			_templateMap.insert(std::make_pair(QString::fromStdString(s), twi));
		}
	}

} /* namespace widgets */
} /* namespace particleEditor */
} /* namespace i6engine */
<|endoftext|>