mirror of
https://github.com/overte-org/overte.git
synced 2025-04-23 12:13:40 +02:00
fixing bad merge
This commit is contained in:
parent
36d21e812d
commit
4c77d9f1d2
24 changed files with 0 additions and 1916 deletions
cmake/modules
interface
external/OpenCV/lib/Win32
opencv_calib3d.libopencv_contrib.libopencv_core.libopencv_features2d.libopencv_flann.libopencv_gpu.libopencv_haartraining_engine.libopencv_highgui.libopencv_imgproc.libopencv_legacy.libopencv_ml.libopencv_nonfree.libopencv_objdetect.libopencv_photo.libopencv_stitching.libopencv_superres.libopencv_ts.libopencv_video.libopencv_videostab.lib
src
|
@ -1,50 +0,0 @@
|
|||
# Find the OpenCV library
|
||||
#
|
||||
# You must provide an OPENCV_ROOT_DIR which contains lib and include directories
|
||||
#
|
||||
# Once done this will define
|
||||
#
|
||||
# OPENCV_FOUND - system found OpenCV
|
||||
# OPENCV_INCLUDE_DIRS - the OpenCV include directory
|
||||
# OPENCV_LIBRARIES - Link this to use OpenCV
|
||||
#
|
||||
# Created on 6/13/2013 by Andrzej Kapolka
|
||||
# Copyright (c) 2013 High Fidelity
|
||||
#
|
||||
|
||||
if (OPENCV_LIBRARIES AND OPENCV_INCLUDE_DIRS)
|
||||
# in cache already
|
||||
set(OPENCV_FOUND TRUE)
|
||||
else (OPENCV_LIBRARIES AND OPENCV_INCLUDE_DIRS)
|
||||
find_path(OPENCV_INCLUDE_DIRS opencv2/opencv.hpp ${OPENCV_ROOT_DIR}/include)
|
||||
|
||||
foreach (MODULE core flann imgproc photo video features2d objdetect calib3d ml highgui contrib)
|
||||
if (APPLE)
|
||||
find_library(OPENCV_LIBRARY_${MODULE} libopencv_${MODULE}.a ${OPENCV_ROOT_DIR}/lib/MacOS/)
|
||||
elseif (UNIX)
|
||||
find_library(OPENCV_LIBRARY_${MODULE} libopencv_${MODULE}.a ${OPENCV_ROOT_DIR}/lib/UNIX/)
|
||||
elseif (WIN32)
|
||||
find_library(OPENCV_LIBRARY_${MODULE} opencv_${MODULE}.lib ${OPENCV_ROOT_DIR}/lib/Win32/)
|
||||
endif ()
|
||||
set(MODULE_LIBRARIES ${OPENCV_LIBRARY_${MODULE}} ${MODULE_LIBRARIES})
|
||||
endforeach (MODULE)
|
||||
set(OPENCV_LIBRARIES ${MODULE_LIBRARIES} CACHE STRING "OpenCV library paths")
|
||||
|
||||
if (OPENCV_INCLUDE_DIRS AND OPENCV_LIBRARIES)
|
||||
set(OPENCV_FOUND TRUE)
|
||||
endif (OPENCV_INCLUDE_DIRS AND OPENCV_LIBRARIES)
|
||||
|
||||
if (OPENCV_FOUND)
|
||||
if (NOT OPENCV_FIND_QUIETLY)
|
||||
message(STATUS "Found OpenCV: ${OPENCV_LIBRARIES}")
|
||||
endif (NOT OPENCV_FIND_QUIETLY)
|
||||
else (OPENCV_FOUND)
|
||||
if (OPENCV_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "Could not find OpenCV")
|
||||
endif (OPENCV_FIND_REQUIRED)
|
||||
endif (OPENCV_FOUND)
|
||||
|
||||
# show the OPENCV_INCLUDE_DIRS and OPENCV_LIBRARIES variables only in the advanced view
|
||||
mark_as_advanced(OPENCV_INCLUDE_DIRS OPENCV_LIBRARIES)
|
||||
|
||||
endif (OPENCV_LIBRARIES AND OPENCV_INCLUDE_DIRS)
|
Binary file not shown.
Binary file not shown.
BIN
interface/external/OpenCV/lib/Win32/opencv_core.lib
vendored
BIN
interface/external/OpenCV/lib/Win32/opencv_core.lib
vendored
Binary file not shown.
Binary file not shown.
BIN
interface/external/OpenCV/lib/Win32/opencv_flann.lib
vendored
BIN
interface/external/OpenCV/lib/Win32/opencv_flann.lib
vendored
Binary file not shown.
BIN
interface/external/OpenCV/lib/Win32/opencv_gpu.lib
vendored
BIN
interface/external/OpenCV/lib/Win32/opencv_gpu.lib
vendored
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
interface/external/OpenCV/lib/Win32/opencv_ml.lib
vendored
BIN
interface/external/OpenCV/lib/Win32/opencv_ml.lib
vendored
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
interface/external/OpenCV/lib/Win32/opencv_photo.lib
vendored
BIN
interface/external/OpenCV/lib/Win32/opencv_photo.lib
vendored
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
interface/external/OpenCV/lib/Win32/opencv_ts.lib
vendored
BIN
interface/external/OpenCV/lib/Win32/opencv_ts.lib
vendored
Binary file not shown.
BIN
interface/external/OpenCV/lib/Win32/opencv_video.lib
vendored
BIN
interface/external/OpenCV/lib/Win32/opencv_video.lib
vendored
Binary file not shown.
Binary file not shown.
|
@ -1,501 +0,0 @@
|
|||
//
|
||||
// VideoFace.cpp
|
||||
// interface
|
||||
//
|
||||
// Created by Andrzej Kapolka on 7/11/13.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
|
||||
#ifdef HAVE_LIBVPX
|
||||
#include <vpx_decoder.h>
|
||||
#include <vp8dx.h>
|
||||
#endif
|
||||
|
||||
#include <PacketHeaders.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "Avatar.h"
|
||||
#include "Head.h"
|
||||
#include "VideoFace.h"
|
||||
#include "renderer/ProgramObject.h"
|
||||
|
||||
using namespace cv;
|
||||
|
||||
bool VideoFace::_initialized = false;
|
||||
ProgramObject VideoFace::_videoProgram;
|
||||
VideoFace::Locations VideoFace::_videoProgramLocations;
|
||||
ProgramObject VideoFace::_texturedProgram;
|
||||
VideoFace::Locations VideoFace::_texturedProgramLocations;
|
||||
GLuint VideoFace::_vboID;
|
||||
GLuint VideoFace::_iboID;
|
||||
|
||||
VideoFace::VideoFace(Head* owningHead) : _owningHead(owningHead), _renderMode(MESH),
|
||||
_colorTextureID(0), _depthTextureID(0),
|
||||
#ifdef HAVE_LIBVPX
|
||||
_colorCodec(), _depthCodec(),
|
||||
#endif
|
||||
_frameCount(0) {
|
||||
// we may have been created in the network thread, but we live in the main thread
|
||||
moveToThread(Application::getInstance()->thread());
|
||||
}
|
||||
|
||||
VideoFace::~VideoFace() {
|
||||
#ifdef HAVE_LIBVPX
|
||||
if (_colorCodec.name != 0) {
|
||||
vpx_codec_destroy(&_colorCodec);
|
||||
|
||||
// delete our texture, since we know that we own it
|
||||
if (_colorTextureID != 0) {
|
||||
glDeleteTextures(1, &_colorTextureID);
|
||||
}
|
||||
|
||||
}
|
||||
if (_depthCodec.name != 0) {
|
||||
vpx_codec_destroy(&_depthCodec);
|
||||
|
||||
// delete our texture, since we know that we own it
|
||||
if (_depthTextureID != 0) {
|
||||
glDeleteTextures(1, &_depthTextureID);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void VideoFace::setFrameFromWebcam() {
|
||||
Webcam* webcam = Application::getInstance()->getWebcam();
|
||||
if (webcam->isSending()) {
|
||||
_colorTextureID = webcam->getColorTextureID();
|
||||
_depthTextureID = webcam->getDepthTextureID();
|
||||
_textureSize = webcam->getTextureSize();
|
||||
_textureRect = webcam->getFaceRect();
|
||||
_aspectRatio = webcam->getAspectRatio();
|
||||
} else {
|
||||
clearFrame();
|
||||
}
|
||||
}
|
||||
|
||||
void VideoFace::clearFrame() {
|
||||
_colorTextureID = 0;
|
||||
_depthTextureID = 0;
|
||||
}
|
||||
|
||||
int VideoFace::processVideoMessage(unsigned char* packetData, size_t dataBytes) {
|
||||
#ifdef HAVE_LIBVPX
|
||||
unsigned char* packetPosition = packetData;
|
||||
|
||||
int frameCount = *(uint32_t*)packetPosition;
|
||||
packetPosition += sizeof(uint32_t);
|
||||
|
||||
int frameSize = *(uint32_t*)packetPosition;
|
||||
packetPosition += sizeof(uint32_t);
|
||||
|
||||
int frameOffset = *(uint32_t*)packetPosition;
|
||||
packetPosition += sizeof(uint32_t);
|
||||
|
||||
if (frameCount < _frameCount) { // old frame; ignore
|
||||
return dataBytes;
|
||||
|
||||
} else if (frameCount > _frameCount) { // new frame; reset
|
||||
_frameCount = frameCount;
|
||||
_frameBytesRemaining = frameSize;
|
||||
_arrivingFrame.resize(frameSize);
|
||||
}
|
||||
|
||||
int payloadSize = dataBytes - (packetPosition - packetData);
|
||||
memcpy(_arrivingFrame.data() + frameOffset, packetPosition, payloadSize);
|
||||
|
||||
if ((_frameBytesRemaining -= payloadSize) > 0) {
|
||||
return dataBytes; // wait for the rest of the frame
|
||||
}
|
||||
|
||||
if (frameSize == 0) {
|
||||
// destroy the codecs, if we have any
|
||||
destroyCodecs();
|
||||
|
||||
// disables video data
|
||||
QMetaObject::invokeMethod(this, "setFrame", Q_ARG(cv::Mat, Mat()),
|
||||
Q_ARG(cv::Mat, Mat()), Q_ARG(float, 0.0f));
|
||||
return dataBytes;
|
||||
}
|
||||
|
||||
// the switch between full frame or depth only modes requires us to reinit the codecs
|
||||
float aspectRatio = *(const float*)_arrivingFrame.constData();
|
||||
size_t colorSize = *(const size_t*)(_arrivingFrame.constData() + sizeof(float));
|
||||
bool fullFrame = (aspectRatio == FULL_FRAME_ASPECT);
|
||||
bool depthOnly = (colorSize == 0);
|
||||
if (fullFrame != _lastFullFrame || depthOnly != _lastDepthOnly) {
|
||||
destroyCodecs();
|
||||
_lastFullFrame = fullFrame;
|
||||
_lastDepthOnly = depthOnly;
|
||||
}
|
||||
|
||||
// read the color data, if non-empty
|
||||
Mat color;
|
||||
const uint8_t* colorData = (const uint8_t*)(_arrivingFrame.constData() + sizeof(float) + sizeof(size_t));
|
||||
if (colorSize > 0) {
|
||||
if (_colorCodec.name == 0) {
|
||||
// initialize decoder context
|
||||
vpx_codec_dec_init(&_colorCodec, vpx_codec_vp8_dx(), 0, 0);
|
||||
}
|
||||
vpx_codec_decode(&_colorCodec, colorData, colorSize, 0, 0);
|
||||
vpx_codec_iter_t iterator = 0;
|
||||
vpx_image_t* image;
|
||||
while ((image = vpx_codec_get_frame(&_colorCodec, &iterator)) != 0) {
|
||||
// convert from YV12 to RGB: see http://www.fourcc.org/yuv.php and
|
||||
// http://docs.opencv.org/modules/imgproc/doc/miscellaneous_transformations.html#cvtcolor
|
||||
color.create(image->d_h, image->d_w, CV_8UC3);
|
||||
uchar* yline = image->planes[0];
|
||||
uchar* vline = image->planes[1];
|
||||
uchar* uline = image->planes[2];
|
||||
const int RED_V_WEIGHT = (int)(1.403 * 256);
|
||||
const int GREEN_V_WEIGHT = (int)(0.714 * 256);
|
||||
const int GREEN_U_WEIGHT = (int)(0.344 * 256);
|
||||
const int BLUE_U_WEIGHT = (int)(1.773 * 256);
|
||||
for (int i = 0; i < image->d_h; i += 2) {
|
||||
uchar* ysrc = yline;
|
||||
uchar* vsrc = vline;
|
||||
uchar* usrc = uline;
|
||||
for (int j = 0; j < image->d_w; j += 2) {
|
||||
uchar* tl = color.ptr(i, j);
|
||||
uchar* tr = color.ptr(i, j + 1);
|
||||
uchar* bl = color.ptr(i + 1, j);
|
||||
uchar* br = color.ptr(i + 1, j + 1);
|
||||
|
||||
int v = *vsrc++ - 128;
|
||||
int u = *usrc++ - 128;
|
||||
|
||||
int redOffset = (RED_V_WEIGHT * v) >> 8;
|
||||
int greenOffset = (GREEN_V_WEIGHT * v + GREEN_U_WEIGHT * u) >> 8;
|
||||
int blueOffset = (BLUE_U_WEIGHT * u) >> 8;
|
||||
|
||||
int ytl = ysrc[0];
|
||||
int ytr = ysrc[1];
|
||||
int ybl = ysrc[image->w];
|
||||
int ybr = ysrc[image->w + 1];
|
||||
ysrc += 2;
|
||||
|
||||
tl[0] = saturate_cast<uchar>(ytl + redOffset);
|
||||
tl[1] = saturate_cast<uchar>(ytl - greenOffset);
|
||||
tl[2] = saturate_cast<uchar>(ytl + blueOffset);
|
||||
|
||||
tr[0] = saturate_cast<uchar>(ytr + redOffset);
|
||||
tr[1] = saturate_cast<uchar>(ytr - greenOffset);
|
||||
tr[2] = saturate_cast<uchar>(ytr + blueOffset);
|
||||
|
||||
bl[0] = saturate_cast<uchar>(ybl + redOffset);
|
||||
bl[1] = saturate_cast<uchar>(ybl - greenOffset);
|
||||
bl[2] = saturate_cast<uchar>(ybl + blueOffset);
|
||||
|
||||
br[0] = saturate_cast<uchar>(ybr + redOffset);
|
||||
br[1] = saturate_cast<uchar>(ybr - greenOffset);
|
||||
br[2] = saturate_cast<uchar>(ybr + blueOffset);
|
||||
}
|
||||
yline += image->stride[0] * 2;
|
||||
vline += image->stride[1];
|
||||
uline += image->stride[2];
|
||||
}
|
||||
}
|
||||
} else if (_colorCodec.name != 0) {
|
||||
vpx_codec_destroy(&_colorCodec);
|
||||
_colorCodec.name = 0;
|
||||
}
|
||||
|
||||
// read the depth data, if non-empty
|
||||
Mat depth;
|
||||
const uint8_t* depthData = colorData + colorSize;
|
||||
int depthSize = _arrivingFrame.size() - ((const char*)depthData - _arrivingFrame.constData());
|
||||
|
||||
if (depthSize > 0) {
|
||||
if (_depthCodec.name == 0) {
|
||||
// initialize decoder context
|
||||
vpx_codec_dec_init(&_depthCodec, vpx_codec_vp8_dx(), 0, 0);
|
||||
}
|
||||
vpx_codec_decode(&_depthCodec, depthData, depthSize, 0, 0);
|
||||
vpx_codec_iter_t iterator = 0;
|
||||
vpx_image_t* image;
|
||||
while ((image = vpx_codec_get_frame(&_depthCodec, &iterator)) != 0) {
|
||||
depth.create(image->d_h, image->d_w, CV_8UC1);
|
||||
uchar* yline = image->planes[0];
|
||||
uchar* vline = image->planes[1];
|
||||
const uchar EIGHT_BIT_MAXIMUM = 255;
|
||||
const uchar MASK_THRESHOLD = 192;
|
||||
for (int i = 0; i < image->d_h; i += 2) {
|
||||
uchar* ysrc = yline;
|
||||
uchar* vsrc = vline;
|
||||
for (int j = 0; j < image->d_w; j += 2) {
|
||||
if (*vsrc++ < MASK_THRESHOLD) {
|
||||
*depth.ptr(i, j) = EIGHT_BIT_MAXIMUM;
|
||||
*depth.ptr(i, j + 1) = EIGHT_BIT_MAXIMUM;
|
||||
*depth.ptr(i + 1, j) = EIGHT_BIT_MAXIMUM;
|
||||
*depth.ptr(i + 1, j + 1) = EIGHT_BIT_MAXIMUM;
|
||||
|
||||
} else {
|
||||
*depth.ptr(i, j) = ysrc[0];
|
||||
*depth.ptr(i, j + 1) = ysrc[1];
|
||||
*depth.ptr(i + 1, j) = ysrc[image->stride[0]];
|
||||
*depth.ptr(i + 1, j + 1) = ysrc[image->stride[0] + 1];
|
||||
}
|
||||
ysrc += 2;
|
||||
}
|
||||
yline += image->stride[0] * 2;
|
||||
vline += image->stride[1];
|
||||
}
|
||||
}
|
||||
} else if (_depthCodec.name != 0) {
|
||||
vpx_codec_destroy(&_depthCodec);
|
||||
_depthCodec.name = 0;
|
||||
}
|
||||
QMetaObject::invokeMethod(this, "setFrame", Q_ARG(cv::Mat, color),
|
||||
Q_ARG(cv::Mat, depth), Q_ARG(float, aspectRatio));
|
||||
#endif
|
||||
|
||||
return dataBytes;
|
||||
}
|
||||
|
||||
bool VideoFace::render(float alpha) {
|
||||
#ifndef HAVE_LIBVPX
|
||||
return false;
|
||||
#else
|
||||
if (!isActive()) {
|
||||
return false;
|
||||
}
|
||||
glPushMatrix();
|
||||
|
||||
glTranslatef(_owningHead->getPosition().x, _owningHead->getPosition().y, _owningHead->getPosition().z);
|
||||
glm::quat orientation = _owningHead->getOrientation();
|
||||
glm::vec3 axis = glm::axis(orientation);
|
||||
glRotatef(glm::angle(orientation), axis.x, axis.y, axis.z);
|
||||
|
||||
float aspect, xScale, zScale;
|
||||
if (_aspectRatio == FULL_FRAME_ASPECT) {
|
||||
aspect = _textureSize.width / _textureSize.height;
|
||||
const float FULL_FRAME_SCALE = 0.5f;
|
||||
xScale = FULL_FRAME_SCALE * _owningHead->getScale();
|
||||
zScale = xScale * 0.3f;
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(0.0f, -0.2f, 0.0f);
|
||||
glScalef(0.5f * xScale, xScale / aspect, zScale);
|
||||
glColor4f(1.0f, 1.0f, 1.0f, alpha);
|
||||
Application::getInstance()->getGeometryCache()->renderHalfCylinder(25, 20);
|
||||
glPopMatrix();
|
||||
} else {
|
||||
aspect = _aspectRatio;
|
||||
xScale = BODY_BALL_RADIUS_HEAD_BASE * _owningHead->getScale();
|
||||
zScale = xScale * 1.5f;
|
||||
glTranslatef(0.0f, -xScale * 0.75f, -xScale);
|
||||
}
|
||||
glScalef(xScale, xScale / aspect, zScale);
|
||||
|
||||
glColor4f(1.0f, 1.0f, 1.0f, alpha);
|
||||
|
||||
Point2f points[4];
|
||||
_textureRect.points(points);
|
||||
|
||||
if (_depthTextureID != 0) {
|
||||
const int VERTEX_WIDTH = 100;
|
||||
const int VERTEX_HEIGHT = 100;
|
||||
const int VERTEX_COUNT = VERTEX_WIDTH * VERTEX_HEIGHT;
|
||||
const int ELEMENTS_PER_VERTEX = 2;
|
||||
const int BUFFER_ELEMENTS = VERTEX_COUNT * ELEMENTS_PER_VERTEX;
|
||||
const int QUAD_WIDTH = VERTEX_WIDTH - 1;
|
||||
const int QUAD_HEIGHT = VERTEX_HEIGHT - 1;
|
||||
const int QUAD_COUNT = QUAD_WIDTH * QUAD_HEIGHT;
|
||||
const int TRIANGLES_PER_QUAD = 2;
|
||||
const int INDICES_PER_TRIANGLE = 3;
|
||||
const int INDEX_COUNT = QUAD_COUNT * TRIANGLES_PER_QUAD * INDICES_PER_TRIANGLE;
|
||||
|
||||
if (!_initialized) {
|
||||
loadProgram(_videoProgram, QString(), "colorTexture", _videoProgramLocations);
|
||||
loadProgram(_texturedProgram, "_textured", "permutationNormalTexture", _texturedProgramLocations);
|
||||
|
||||
glGenBuffers(1, &_vboID);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vboID);
|
||||
float* vertices = new float[BUFFER_ELEMENTS];
|
||||
float* vertexPosition = vertices;
|
||||
for (int i = 0; i < VERTEX_HEIGHT; i++) {
|
||||
for (int j = 0; j < VERTEX_WIDTH; j++) {
|
||||
*vertexPosition++ = j / (float)(VERTEX_WIDTH - 1);
|
||||
*vertexPosition++ = i / (float)(VERTEX_HEIGHT - 1);
|
||||
}
|
||||
}
|
||||
glBufferData(GL_ARRAY_BUFFER, BUFFER_ELEMENTS * sizeof(float), vertices, GL_STATIC_DRAW);
|
||||
delete[] vertices;
|
||||
|
||||
glGenBuffers(1, &_iboID);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _iboID);
|
||||
int* indices = new int[INDEX_COUNT];
|
||||
int* indexPosition = indices;
|
||||
for (int i = 0; i < QUAD_HEIGHT; i++) {
|
||||
for (int j = 0; j < QUAD_WIDTH; j++) {
|
||||
*indexPosition++ = i * VERTEX_WIDTH + j;
|
||||
*indexPosition++ = (i + 1) * VERTEX_WIDTH + j;
|
||||
*indexPosition++ = i * VERTEX_WIDTH + j + 1;
|
||||
|
||||
*indexPosition++ = i * VERTEX_WIDTH + j + 1;
|
||||
*indexPosition++ = (i + 1) * VERTEX_WIDTH + j;
|
||||
*indexPosition++ = (i + 1) * VERTEX_WIDTH + j + 1;
|
||||
}
|
||||
}
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, INDEX_COUNT * sizeof(int), indices, GL_STATIC_DRAW);
|
||||
delete[] indices;
|
||||
|
||||
_initialized = true;
|
||||
} else {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vboID);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _iboID);
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, _depthTextureID);
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
|
||||
ProgramObject* program = &_videoProgram;
|
||||
Locations* locations = &_videoProgramLocations;
|
||||
if (_colorTextureID != 0) {
|
||||
glBindTexture(GL_TEXTURE_2D, _colorTextureID);
|
||||
|
||||
} else {
|
||||
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPermutationNormalTextureID());
|
||||
program = &_texturedProgram;
|
||||
locations = &_texturedProgramLocations;
|
||||
}
|
||||
program->bind();
|
||||
program->setUniformValue(locations->texCoordCorner,
|
||||
points[0].x / _textureSize.width, points[0].y / _textureSize.height);
|
||||
program->setUniformValue(locations->texCoordRight,
|
||||
(points[3].x - points[0].x) / _textureSize.width, (points[3].y - points[0].y) / _textureSize.height);
|
||||
program->setUniformValue(locations->texCoordUp,
|
||||
(points[1].x - points[0].x) / _textureSize.width, (points[1].y - points[0].y) / _textureSize.height);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glVertexPointer(2, GL_FLOAT, 0, 0);
|
||||
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
glAlphaFunc(GL_EQUAL, 1.0f);
|
||||
|
||||
if (_renderMode == MESH) {
|
||||
glDrawRangeElementsEXT(GL_TRIANGLES, 0, VERTEX_COUNT - 1, INDEX_COUNT, GL_UNSIGNED_INT, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
|
||||
} else { // _renderMode == POINTS
|
||||
glPointSize(5.0f);
|
||||
glDrawArrays(GL_POINTS, 0, VERTEX_COUNT);
|
||||
glPointSize(1.0f);
|
||||
}
|
||||
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
program->release();
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
} else {
|
||||
glBindTexture(GL_TEXTURE_2D, _colorTextureID);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(points[0].x / _textureSize.width, points[0].y / _textureSize.height);
|
||||
glVertex3f(0.5f, -0.5f, 0.0f);
|
||||
glTexCoord2f(points[1].x / _textureSize.width, points[1].y / _textureSize.height);
|
||||
glVertex3f(0.5f, 0.5f, 0.0f);
|
||||
glTexCoord2f(points[2].x / _textureSize.width, points[2].y / _textureSize.height);
|
||||
glVertex3f(-0.5f, 0.5f, 0.0f);
|
||||
glTexCoord2f(points[3].x / _textureSize.width, points[3].y / _textureSize.height);
|
||||
glVertex3f(-0.5f, -0.5f, 0.0f);
|
||||
glEnd();
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void VideoFace::cycleRenderMode() {
|
||||
_renderMode = (RenderMode)((_renderMode + 1) % RENDER_MODE_COUNT);
|
||||
}
|
||||
|
||||
void VideoFace::setFrame(const cv::Mat& color, const cv::Mat& depth, float aspectRatio) {
|
||||
Size2f textureSize = _textureSize;
|
||||
if (!color.empty()) {
|
||||
bool generate = (_colorTextureID == 0);
|
||||
if (generate) {
|
||||
glGenTextures(1, &_colorTextureID);
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, _colorTextureID);
|
||||
if (_textureSize.width != color.cols || _textureSize.height != color.rows || generate) {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, color.cols, color.rows, 0, GL_RGB, GL_UNSIGNED_BYTE, color.ptr());
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
textureSize = color.size();
|
||||
_textureRect = RotatedRect(Point2f(color.cols * 0.5f, color.rows * 0.5f), textureSize, 0.0f);
|
||||
|
||||
} else {
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, color.cols, color.rows, GL_RGB, GL_UNSIGNED_BYTE, color.ptr());
|
||||
}
|
||||
} else if (_colorTextureID != 0) {
|
||||
glDeleteTextures(1, &_colorTextureID);
|
||||
_colorTextureID = 0;
|
||||
}
|
||||
|
||||
if (!depth.empty()) {
|
||||
bool generate = (_depthTextureID == 0);
|
||||
if (generate) {
|
||||
glGenTextures(1, &_depthTextureID);
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, _depthTextureID);
|
||||
if (_textureSize.width != depth.cols || _textureSize.height != depth.rows || generate) {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, depth.cols, depth.rows, 0,
|
||||
GL_LUMINANCE, GL_UNSIGNED_BYTE, depth.ptr());
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
textureSize = depth.size();
|
||||
_textureRect = RotatedRect(Point2f(depth.cols * 0.5f, depth.rows * 0.5f), textureSize, 0.0f);
|
||||
|
||||
} else {
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, depth.cols, depth.rows, GL_LUMINANCE, GL_UNSIGNED_BYTE, depth.ptr());
|
||||
}
|
||||
} else if (_depthTextureID != 0) {
|
||||
glDeleteTextures(1, &_depthTextureID);
|
||||
_depthTextureID = 0;
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
_aspectRatio = aspectRatio;
|
||||
_textureSize = textureSize;
|
||||
}
|
||||
|
||||
void VideoFace::destroyCodecs() {
|
||||
#ifdef HAVE_LIBVPX
|
||||
if (_colorCodec.name != 0) {
|
||||
vpx_codec_destroy(&_colorCodec);
|
||||
_colorCodec.name = 0;
|
||||
}
|
||||
if (_depthCodec.name != 0) {
|
||||
vpx_codec_destroy(&_depthCodec);
|
||||
_depthCodec.name = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void VideoFace::loadProgram(ProgramObject& program, const QString& suffix, const char* secondTextureUniform, Locations& locations) {
|
||||
program.addShaderFromSourceFile(QGLShader::Vertex, "resources/shaders/face" + suffix + ".vert");
|
||||
program.addShaderFromSourceFile(QGLShader::Fragment, "resources/shaders/face" + suffix + ".frag");
|
||||
program.link();
|
||||
|
||||
program.bind();
|
||||
program.setUniformValue("depthTexture", 0);
|
||||
program.setUniformValue(secondTextureUniform, 1);
|
||||
program.release();
|
||||
|
||||
locations.texCoordCorner = program.uniformLocation("texCoordCorner");
|
||||
locations.texCoordRight = program.uniformLocation("texCoordRight");
|
||||
locations.texCoordUp = program.uniformLocation("texCoordUp");
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
//
|
||||
// VideoFace.h
|
||||
// interface
|
||||
//
|
||||
// Created by Andrzej Kapolka on 7/11/13.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __interface__VideoFace__
|
||||
#define __interface__VideoFace__
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
#ifdef HAVE_LIBVPX
|
||||
#include <vpx_codec.h>
|
||||
#endif
|
||||
|
||||
#include "InterfaceConfig.h"
|
||||
|
||||
class Head;
|
||||
class ProgramObject;
|
||||
|
||||
const float FULL_FRAME_ASPECT = 0.0f;
|
||||
|
||||
class VideoFace : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
VideoFace(Head* owningHead);
|
||||
~VideoFace();
|
||||
|
||||
bool isActive() const { return _colorTextureID != 0 || _depthTextureID != 0; }
|
||||
bool isFullFrame() const { return isActive() && _aspectRatio == FULL_FRAME_ASPECT; }
|
||||
|
||||
void setFrameFromWebcam();
|
||||
void clearFrame();
|
||||
|
||||
int processVideoMessage(unsigned char* packetData, size_t dataBytes);
|
||||
|
||||
bool render(float alpha);
|
||||
|
||||
public slots:
|
||||
|
||||
void cycleRenderMode();
|
||||
|
||||
private slots:
|
||||
|
||||
void setFrame(const cv::Mat& color, const cv::Mat& depth, float aspectRatio);
|
||||
|
||||
private:
|
||||
|
||||
enum RenderMode { MESH, POINTS, RENDER_MODE_COUNT };
|
||||
|
||||
void destroyCodecs();
|
||||
|
||||
Head* _owningHead;
|
||||
RenderMode _renderMode;
|
||||
GLuint _colorTextureID;
|
||||
GLuint _depthTextureID;
|
||||
cv::Size2f _textureSize;
|
||||
cv::RotatedRect _textureRect;
|
||||
float _aspectRatio;
|
||||
|
||||
#ifdef HAVE_LIBVPX
|
||||
vpx_codec_ctx_t _colorCodec;
|
||||
vpx_codec_ctx_t _depthCodec;
|
||||
#endif
|
||||
bool _lastFullFrame;
|
||||
bool _lastDepthOnly;
|
||||
|
||||
QByteArray _arrivingFrame;
|
||||
int _frameCount;
|
||||
int _frameBytesRemaining;
|
||||
|
||||
struct Locations {
|
||||
int texCoordCorner;
|
||||
int texCoordRight;
|
||||
int texCoordUp;
|
||||
};
|
||||
|
||||
static void loadProgram(ProgramObject& progam, const QString& suffix, const char* secondTextureUniform, Locations& locations);
|
||||
|
||||
static bool _initialized;
|
||||
|
||||
static ProgramObject _videoProgram;
|
||||
static Locations _videoProgramLocations;
|
||||
|
||||
static ProgramObject _texturedProgram;
|
||||
static Locations _texturedProgramLocations;
|
||||
|
||||
static GLuint _vboID;
|
||||
static GLuint _iboID;
|
||||
};
|
||||
|
||||
#endif /* defined(__interface__VideoFace__) */
|
File diff suppressed because it is too large
Load diff
|
@ -1,207 +0,0 @@
|
|||
//
|
||||
// Webcam.h
|
||||
// interface
|
||||
//
|
||||
// Created by Andrzej Kapolka on 6/17/13.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __interface__Webcam__
|
||||
#define __interface__Webcam__
|
||||
|
||||
#include <QMetaType>
|
||||
#include <QThread>
|
||||
#include <QVector>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
#if defined(HAVE_OPENNI) && !defined(Q_MOC_RUN)
|
||||
#include <XnCppWrapper.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBVPX
|
||||
#include <vpx_codec.h>
|
||||
#endif
|
||||
|
||||
#include "InterfaceConfig.h"
|
||||
|
||||
class QImage;
|
||||
|
||||
struct CvCapture;
|
||||
|
||||
class FrameGrabber;
|
||||
class Joint;
|
||||
|
||||
typedef QVector<Joint> JointVector;
|
||||
typedef std::vector<cv::KeyPoint> KeyPointVector;
|
||||
|
||||
/// Handles interaction with the webcam (including depth cameras such as the Kinect).
|
||||
class Webcam : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
Webcam();
|
||||
~Webcam();
|
||||
|
||||
FrameGrabber* getGrabber() { return _grabber; }
|
||||
|
||||
bool isActive() const { return _active; }
|
||||
|
||||
bool isSending() const { return _sending; }
|
||||
|
||||
GLuint getColorTextureID() const { return _colorTextureID; }
|
||||
GLuint getDepthTextureID() const { return _depthTextureID; }
|
||||
const cv::Size2f& getTextureSize() const { return _textureSize; }
|
||||
|
||||
float getAspectRatio() const { return _aspectRatio; }
|
||||
|
||||
const cv::RotatedRect& getFaceRect() const { return _faceRect; }
|
||||
|
||||
const glm::vec3& getEstimatedPosition() const { return _estimatedPosition; }
|
||||
const glm::vec3& getEstimatedRotation() const { return _estimatedRotation; }
|
||||
const JointVector& getEstimatedJoints() const { return _estimatedJoints; }
|
||||
|
||||
void reset();
|
||||
void renderPreview(int screenWidth, int screenHeight);
|
||||
|
||||
public slots:
|
||||
|
||||
void setEnabled(bool enabled);
|
||||
void setFrame(const cv::Mat& color, int format, const cv::Mat& depth, float midFaceDepth, float aspectRatio,
|
||||
const cv::RotatedRect& faceRect, bool sending, const JointVector& joints, const KeyPointVector& keyPoints);
|
||||
void setSkeletonTrackingOn(bool toggle) { _skeletonTrackingOn = toggle; };
|
||||
|
||||
private:
|
||||
|
||||
QThread _grabberThread;
|
||||
FrameGrabber* _grabber;
|
||||
|
||||
bool _enabled;
|
||||
bool _active;
|
||||
bool _sending;
|
||||
GLuint _colorTextureID;
|
||||
GLuint _depthTextureID;
|
||||
cv::Size2f _textureSize;
|
||||
float _aspectRatio;
|
||||
cv::RotatedRect _faceRect;
|
||||
cv::RotatedRect _initialFaceRect;
|
||||
float _initialFaceDepth;
|
||||
JointVector _joints;
|
||||
KeyPointVector _keyPoints;
|
||||
|
||||
glm::quat _initialLEDRotation;
|
||||
glm::vec3 _initialLEDPosition;
|
||||
float _initialLEDScale;
|
||||
|
||||
uint64_t _startTimestamp;
|
||||
int _frameCount;
|
||||
|
||||
uint64_t _lastFrameTimestamp;
|
||||
|
||||
glm::vec3 _estimatedPosition;
|
||||
glm::vec3 _estimatedRotation;
|
||||
JointVector _estimatedJoints;
|
||||
|
||||
bool _skeletonTrackingOn;
|
||||
};
|
||||
|
||||
#ifdef HAVE_LIBVPX
|
||||
|
||||
/// Acquires and processes video frames in a dedicated thread.
|
||||
class FrameGrabber : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
FrameGrabber();
|
||||
virtual ~FrameGrabber();
|
||||
|
||||
public slots:
|
||||
|
||||
void cycleVideoSendMode();
|
||||
void setDepthOnly(bool depthOnly);
|
||||
void setLEDTrackingOn(bool ledTrackingOn);
|
||||
void reset();
|
||||
void shutdown();
|
||||
void grabFrame();
|
||||
|
||||
private:
|
||||
|
||||
enum VideoSendMode { NO_VIDEO, FACE_VIDEO, FULL_FRAME_VIDEO, VIDEO_SEND_MODE_COUNT };
|
||||
|
||||
bool init();
|
||||
void updateHSVFrame(const cv::Mat& frame, int format);
|
||||
void destroyCodecs();
|
||||
void configureCapture();
|
||||
|
||||
bool _initialized;
|
||||
VideoSendMode _videoSendMode;
|
||||
bool _depthOnly;
|
||||
bool _ledTrackingOn;
|
||||
CvCapture* _capture;
|
||||
cv::CascadeClassifier _faceCascade;
|
||||
cv::Mat _hsvFrame;
|
||||
cv::Mat _mask;
|
||||
cv::SparseMat _histogram;
|
||||
cv::Mat _backProject;
|
||||
cv::Rect _searchWindow;
|
||||
cv::Mat _grayDepthFrame;
|
||||
float _smoothedMidFaceDepth;
|
||||
|
||||
#ifdef HAVE_LIBVPX
|
||||
vpx_codec_ctx_t _colorCodec;
|
||||
vpx_codec_ctx_t _depthCodec;
|
||||
#endif
|
||||
int _frameCount;
|
||||
cv::Mat _faceColor;
|
||||
cv::Mat _faceDepth;
|
||||
cv::Mat _smoothedFaceDepth;
|
||||
QByteArray _encodedFace;
|
||||
cv::RotatedRect _smoothedFaceRect;
|
||||
|
||||
cv::SimpleBlobDetector _blobDetector;
|
||||
cv::Mat _grayFrame;
|
||||
|
||||
#ifdef HAVE_OPENNI
|
||||
xn::Context _xnContext;
|
||||
xn::DepthGenerator _depthGenerator;
|
||||
xn::ImageGenerator _imageGenerator;
|
||||
xn::UserGenerator _userGenerator;
|
||||
xn::DepthMetaData _depthMetaData;
|
||||
xn::ImageMetaData _imageMetaData;
|
||||
XnUserID _userID;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif //def HAVE_LIBVPX
|
||||
|
||||
|
||||
/// Contains the 3D transform and 2D projected position of a tracked joint.
|
||||
class Joint {
|
||||
public:
|
||||
|
||||
Joint(const glm::vec3& position, const glm::quat& rotation, const glm::vec3& projected);
|
||||
Joint();
|
||||
|
||||
bool isValid;
|
||||
glm::vec3 position;
|
||||
glm::quat rotation;
|
||||
glm::vec3 projected;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(JointVector)
|
||||
Q_DECLARE_METATYPE(KeyPointVector)
|
||||
|
||||
|
||||
|
||||
#ifdef HAVE_LIBVPX
|
||||
Q_DECLARE_METATYPE(cv::Mat)
|
||||
Q_DECLARE_METATYPE(cv::RotatedRect)
|
||||
#endif //def HAVE_LIBVPX
|
||||
|
||||
|
||||
#endif /* defined(__interface__Webcam__) */
|
Loading…
Reference in a new issue