<commit_before>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2016 BMW Car IT GmbH
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
#include <gtest/gtest.h>
#include <gmock/gmock.h>

#include "joynr/serializer/Serializer.h"
#include "joynr/Request.h"

#include "cluster-controller/mqtt/MqttMessagingSkeleton.h"
#include "tests/utils/MockObjects.h"

using ::testing::A;
using ::testing::_;
using ::testing::Eq;
using ::testing::AllOf;
using ::testing::Property;
using ::testing::Pointee;

using namespace ::testing;
using namespace joynr;

class MqttMessagingSkeletonTest : public ::testing::Test {
public:
    MqttMessagingSkeletonTest() : mockMessageRouter() {}

    void SetUp(){
        // create a fake message
        std::string postFix;
        std::string senderID;
        std::string receiverID;
        std::string requestID;

        postFix = "_" + util::createUuid();
        senderID = "senderId" + postFix;
        receiverID = "receiverID" + postFix;
        requestID = "requestId" + postFix;
        MessagingQos qosSettings = MessagingQos(456000);
        Request request;
        request.setMethodName("methodName");
        request.setParams(42, std::string("value"));
        std::vector<std::string> paramDatatypes;
        paramDatatypes.push_back("Integer");
        paramDatatypes.push_back("String");
        request.setParamDatatypes(paramDatatypes);

        JoynrMessageFactory messageFactory;
        message = messageFactory.createRequest(
                senderID,
                receiverID,
                qosSettings,
                request
                );
    }

    void TearDown(){
    }
protected:
    MockMessageRouter mockMessageRouter;
    JoynrMessage message;
};

MATCHER_P(pointerToMqttAddressWithChannelId, channelId, "") {
    if (arg == nullptr) {
        return false;
    }
    std::shared_ptr<const joynr::system::RoutingTypes::MqttAddress> mqttAddress = std::dynamic_pointer_cast<const joynr::system::RoutingTypes::MqttAddress>(arg);
    if (mqttAddress == nullptr) {
        return false;
    }
    return mqttAddress->getTopic() == channelId;
}

TEST_F(MqttMessagingSkeletonTest, transmitTest) {
    MqttMessagingSkeleton mqttMessagingSkeleton(mockMessageRouter);
    std::string replyAddress = message.getHeaderReplyAddress();
    EXPECT_CALL(mockMessageRouter, addNextHop(
        _,
        AnyOf(
            Pointee(A<joynr::system::RoutingTypes::Address>()),
            pointerToMqttAddressWithChannelId(replyAddress)
        ),
        _)
    ).Times(1);
    EXPECT_CALL(mockMessageRouter, route(message,_)).Times(1);

    auto onFailure = [](const exceptions::JoynrRuntimeException& e) {
        FAIL() << "onFailure called";
    };
    mqttMessagingSkeleton.transmit(message,onFailure);
}

TEST_F(MqttMessagingSkeletonTest, onTextMessageReceivedTest) {
    MqttMessagingSkeleton mqttMessagingSkeleton(mockMessageRouter);
    std::string serializedMessage = serializer::serializeToJson(message);
    EXPECT_CALL(mockMessageRouter, route(AllOf(Property(&JoynrMessage::getType, Eq(message.getType())),
                                            Property(&JoynrMessage::getPayload, Eq(message.getPayload()))),_)).Times(1);
    mqttMessagingSkeleton.onTextMessageReceived(serializedMessage);
}
<commit_msg>[C++] fixed MqttMessagingSkeletonTest<commit_after>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2016 BMW Car IT GmbH
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
#include <gtest/gtest.h>
#include <gmock/gmock.h>

#include "joynr/serializer/Serializer.h"
#include "joynr/Request.h"
#include "joynr/system/RoutingTypes/MqttAddress.h"

#include "cluster-controller/mqtt/MqttMessagingSkeleton.h"
#include "tests/utils/MockObjects.h"

using ::testing::A;
using ::testing::_;
using ::testing::Eq;
using ::testing::AllOf;
using ::testing::Property;
using ::testing::Pointee;

using namespace ::testing;
using namespace joynr;

class MqttMessagingSkeletonTest : public ::testing::Test {
public:
    MqttMessagingSkeletonTest() : mockMessageRouter() {}

    void SetUp(){
        // create a fake message
        std::string postFix;
        std::string senderID;
        std::string receiverID;
        std::string requestID;

        postFix = "_" + util::createUuid();
        senderID = "senderId" + postFix;
        receiverID = "receiverID" + postFix;
        requestID = "requestId" + postFix;
        MessagingQos qosSettings = MessagingQos(456000);
        Request request;
        request.setMethodName("methodName");
        request.setParams(42, std::string("value"));
        std::vector<std::string> paramDatatypes;
        paramDatatypes.push_back("Integer");
        paramDatatypes.push_back("String");
        request.setParamDatatypes(paramDatatypes);

        JoynrMessageFactory messageFactory;
        message = messageFactory.createRequest(
                senderID,
                receiverID,
                qosSettings,
                request
                );
        joynr::system::RoutingTypes::MqttAddress replyAddress;
        replyAddressSerialized = joynr::serializer::serializeToJson(replyAddress);
        message.setHeaderReplyAddress(replyAddressSerialized);
    }

    void TearDown(){
    }
protected:
    MockMessageRouter mockMessageRouter;
    JoynrMessage message;
    std::string replyAddressSerialized;
};

MATCHER_P(pointerToMqttAddressWithChannelId, channelId, "") {
    if (arg == nullptr) {
        return false;
    }
    std::shared_ptr<const joynr::system::RoutingTypes::MqttAddress> mqttAddress = std::dynamic_pointer_cast<const joynr::system::RoutingTypes::MqttAddress>(arg);
    if (mqttAddress == nullptr) {
        return false;
    }
    return mqttAddress->getTopic() == channelId;
}

TEST_F(MqttMessagingSkeletonTest, transmitTest) {
    MqttMessagingSkeleton mqttMessagingSkeleton(mockMessageRouter);
    EXPECT_CALL(mockMessageRouter, addNextHop(
        _,
        AnyOf(
            Pointee(A<joynr::system::RoutingTypes::Address>()),
            pointerToMqttAddressWithChannelId(replyAddressSerialized)
        ),
        _)
    ).Times(1);
    EXPECT_CALL(mockMessageRouter, route(message,_)).Times(1);

    auto onFailure = [](const exceptions::JoynrRuntimeException& e) {
        FAIL() << "onFailure called";
    };
    mqttMessagingSkeleton.transmit(message,onFailure);
}

TEST_F(MqttMessagingSkeletonTest, onTextMessageReceivedTest) {
    MqttMessagingSkeleton mqttMessagingSkeleton(mockMessageRouter);
    std::string serializedMessage = serializer::serializeToJson(message);
    EXPECT_CALL(mockMessageRouter, route(AllOf(Property(&JoynrMessage::getType, Eq(message.getType())),
                                            Property(&JoynrMessage::getPayload, Eq(message.getPayload()))),_)).Times(1);
    mqttMessagingSkeleton.onTextMessageReceived(serializedMessage);
}
<|endoftext|>


<commit_before>/*
 * The MIT License
 *
 * Copyright (c) 2016 Intel Corporation
 *
 *  Permission is hereby granted, free of charge, to any person
 *  obtaining a copy of this software and associated documentation
 *  files (the "Software"), to deal in the Software without
 *  restriction, including without limitation the rights to use,
 *  copy, modify, merge, publish, distribute, sublicense, and/or
 *  sell copies of the Software, and to permit persons to whom the
 *  Software is furnished to do so, subject to the following
 *  conditions:
 *
 *  The above copyright notice and this permission notice shall be
 *  included in all copies or substantial portions of the
 *  Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
 *  KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 *  WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 *  PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 *  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 *  OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 *  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include <stdlib.h>
#include <string.h>

#include <sys/time.h>
#include "IntelDeflater.h"

extern "C" {
#include "zlib.h"
#include "zconf.h"
#include "igzip_lib.h"
}

#define DEF_MEM_LEVEL 8
//#define DEBUG
//#define profile

#ifdef DEBUG
#  define DBG(M, ...)  fprintf(stdout, "[DEBUG] (%s %s:%d) " M "\n", __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#else
#  define DBG(M, ...)
#endif

static jfieldID FID_lz_stream;
static jfieldID FID_inputBuffer;
static jfieldID FID_inputBufferLength;
static jfieldID FID_endOfStream;
static jfieldID FID_finished;
static jfieldID FID_level;
//static jfieldID FID_inputBufferOffset;

/**
 *  Cache the Java field IDs. Called once when the native library is loaded.
 */
JNIEXPORT void JNICALL Java_com_intel_gkl_compression_IntelDeflater_initNative
(JNIEnv* env, jclass cls) {
  FID_lz_stream = env->GetFieldID(cls, "lz_stream", "J");
  FID_inputBuffer = env->GetFieldID(cls, "inputBuffer", "[B");
  FID_inputBufferLength = env->GetFieldID(cls, "inputBufferLength", "I");
  FID_endOfStream = env->GetFieldID(cls, "endOfStream", "Z");
  FID_finished = env->GetFieldID(cls, "finished", "Z");
  FID_level = env->GetFieldID(cls,"level","I");
//  FID_inputBufferOffset = env->GetFieldID(cls, "inputBufferOffset", "I");

}

/**
 *  Reset the compressor to prepare for new input data. If the stream structure
 *  does not exists yet, it is allocated.
 */
JNIEXPORT void JNICALL Java_com_intel_gkl_compression_IntelDeflater_resetNative
(JNIEnv* env, jobject obj, jboolean nowrap) {

  jint level = env->GetIntField(obj, FID_level);

  if(level == 1 || level ==2) {
    isal_zstream* lz_stream = (isal_zstream*)env->GetLongField(obj, FID_lz_stream);

    if (lz_stream == 0) {
      lz_stream = (isal_zstream*)malloc(sizeof(isal_zstream));
      if ( lz_stream == NULL ) {
        jclass Exception = env->FindClass("java/lang/Exception");
        env->ThrowNew(Exception,"Memory allocation error");
      }

      env->SetLongField(obj, FID_lz_stream, (jlong)lz_stream);

       isal_deflate_stateless_init(lz_stream);

    lz_stream->level = level;
    lz_stream->level_buf = (uint8_t*)malloc(ISAL_DEF_LVL2_DEFAULT);
    lz_stream->level_buf_size = ISAL_DEF_LVL2_DEFAULT;

    }
    else {

      isal_deflate_stateless_init(lz_stream);

    }

    uint8_t *level_buf = NULL;
    lz_stream->level = level;
    jint level_size =ISAL_DEF_LVL2_DEFAULT;
    level_buf = (uint8_t*)malloc(level_size);
    lz_stream->level_buf = level_buf;
    lz_stream->level_buf_size = ISAL_DEF_LVL2_DEFAULT;
    lz_stream->end_of_stream = 0;

   // DBG("lz_stream = 0x%lx", (long)lz_stream);
  }
  else {

    z_stream* lz_stream = (z_stream*)env->GetLongField(obj, FID_lz_stream);

    if (lz_stream == 0) {
      lz_stream = (z_stream*)calloc(1, sizeof(z_stream));
      if ( lz_stream == NULL ) {
        jclass Exception = env->FindClass("java/lang/Exception");
        env->ThrowNew(Exception,"Memory allocation error");
      }
      env->SetLongField(obj, FID_lz_stream, (jlong)lz_stream);

      lz_stream->zalloc = Z_NULL;
      lz_stream->zfree = Z_NULL;
      lz_stream->opaque = Z_NULL;
      int ret = deflateInit2(lz_stream, level,  Z_DEFLATED,
                             nowrap ? -MAX_WBITS : MAX_WBITS,
                             DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
      if (ret != Z_OK) {
        jclass Exception = env->FindClass("java/lang/Exception");
        env->ThrowNew(Exception,"IntelDeflater init error");
      }
    }
    else {
      deflateReset(lz_stream);
    }

  }
}

/**
* Generate Dynamic Huffman tables
* This function will be called only if we are implementing the fully dynamic huffman implementation which is not set as default in current implementation
* current implementation we use semi-dynamic huffman with tables generated using only first 64k block of stream
*/

JNIEXPORT void JNICALL Java_com_intel_gkl_compression_IntelDeflater_generateHuffman
(JNIEnv * env, jobject obj) {

      jbyteArray inputBuffer = (jbyteArray)env->GetObjectField(obj, FID_inputBuffer);

      jint level = env->GetIntField(obj, FID_level);

      if(level == 1) {
      isal_zstream* lz_stream = (isal_zstream*)env->GetLongField(obj, FID_lz_stream);

      jbyte* input = (jbyte*)env->GetPrimitiveArrayCritical(inputBuffer, 0);

      struct isal_huff_histogram *histogram;
      struct isal_hufftables *hufftables_custom;

      memset(histogram, 0, sizeof(isal_huff_histogram));
      isal_update_histogram((unsigned char*)input, 64*1024, histogram);
      isal_create_hufftables(hufftables_custom, histogram);
      lz_stream->hufftables = hufftables_custom;

      env->SetLongField(obj, FID_lz_stream, (jlong)lz_stream);
      env->ReleasePrimitiveArrayCritical(inputBuffer, input, 0);
      }
}

/**
 *  Deflate the data.
 */
JNIEXPORT jint JNICALL Java_com_intel_gkl_compression_IntelDeflater_deflateNative
(JNIEnv * env, jobject obj, jbyteArray outputBuffer, jint outputBufferLength) {

  jbyteArray inputBuffer = (jbyteArray)env->GetObjectField(obj, FID_inputBuffer);
  jint inputBufferLength = env->GetIntField(obj, FID_inputBufferLength);
  //jint inputBufferOffset = env->GetIntField(obj, FID_inputBufferOffset);
  jboolean endOfStream = env->GetBooleanField(obj, FID_endOfStream);
  jint level = env->GetIntField(obj, FID_level);

  if(level == 1 || level ==2 ) {

    isal_zstream* lz_stream = (isal_zstream*)env->GetLongField(obj, FID_lz_stream);

    isal_zstream stream;

    jbyte* next_in = (jbyte*)env->GetPrimitiveArrayCritical(inputBuffer, 0);
    jbyte* next_out = (jbyte*)env->GetPrimitiveArrayCritical(outputBuffer, 0);

    lz_stream->next_in = (UINT8*)(next_in);
    lz_stream->avail_in = inputBufferLength;
    lz_stream->end_of_stream = endOfStream;
    lz_stream->next_out = (UINT8*) (next_out);
    lz_stream->avail_out = outputBufferLength ;

    int bytes_in = inputBufferLength;

#ifdef profile
    struct timeval  tv1, tv2;
    gettimeofday(&tv1, NULL);
#endif

    // compress and update lz_stream state
    isal_deflate_stateless(lz_stream);

#ifdef profile
    gettimeofday(&tv2, NULL);
    DBG ("Total time = %f seconds\n",
             (double) (tv2.tv_usec - tv1.tv_usec) / 1000000 +
             (double) (tv2.tv_sec - tv1.tv_sec));
#endif

    long bytes_out = outputBufferLength - lz_stream->avail_out;

     DBG ("bytes_out = %d \n", bytes_out);
      DBG ("avail_out = %d \n",lz_stream->avail_out );

    // release buffers
    env->ReleasePrimitiveArrayCritical(inputBuffer, next_in, 0);
    env->ReleasePrimitiveArrayCritical(outputBuffer, next_out, 0);

    // set finished if endOfStream was set and all input processed
    if (endOfStream && lz_stream->avail_in == 0) {
      env->SetBooleanField(obj, FID_finished, true);
    }

    // return number of bytes written to output buffer
    return bytes_out;
  }
  else {

    z_stream* lz_stream = (z_stream*)env->GetLongField(obj, FID_lz_stream);

    jbyte* next_in = (jbyte*)env->GetPrimitiveArrayCritical(inputBuffer, 0);
    jbyte* next_out = (jbyte*)env->GetPrimitiveArrayCritical(outputBuffer, 0);

    lz_stream->next_in = (Bytef *) next_in;
    lz_stream->avail_in = (uInt) inputBufferLength;
    lz_stream->next_out = (Bytef *) next_out;
    lz_stream->avail_out = (uInt) outputBufferLength;

    int bytes_in = inputBufferLength;

#ifdef profile
    struct timeval  tv1, tv2;
    gettimeofday(&tv1, NULL);
#endif
    // compress and update lz_stream state
    int ret = deflate(lz_stream, Z_FINISH);

 #ifdef profile
     gettimeofday(&tv2, NULL);

     DBG ("Total time = %f seconds\n",
              (double) (tv2.tv_usec - tv1.tv_usec) / 1000000 +
              (double) (tv2.tv_sec - tv1.tv_sec));
 #endif

    int bytes_out = outputBufferLength - lz_stream->avail_out;

    // release buffers
    env->ReleasePrimitiveArrayCritical(inputBuffer, next_in, 0);
    env->ReleasePrimitiveArrayCritical(outputBuffer, next_out, 0);

    if (ret == Z_STREAM_END && lz_stream->avail_in == 0) {
      env->SetBooleanField(obj, FID_finished, true);
    }

    return bytes_out;
  }
}

/**
 *  Close the compressor and reclaim memory
 */
JNIEXPORT void JNICALL
Java_com_intel_gkl_compression_IntelDeflater_endNative(JNIEnv *env, jobject obj)
{
  jint level = env->GetIntField(obj, FID_level);
   if (level == 1 || level == 2 ) {
     isal_zstream* lz_stream = (isal_zstream*)env->GetLongField(obj, FID_lz_stream);
      free(lz_stream->level_buf);
      free(lz_stream);

   }
  else {
    z_stream* lz_stream = (z_stream*)env->GetLongField(obj, FID_lz_stream);
    deflateEnd(lz_stream);
    free(lz_stream);
  }

}
<commit_msg>update to deflater native code<commit_after>/*
 * The MIT License
 *
 * Copyright (c) 2016 Intel Corporation
 *
 *  Permission is hereby granted, free of charge, to any person
 *  obtaining a copy of this software and associated documentation
 *  files (the "Software"), to deal in the Software without
 *  restriction, including without limitation the rights to use,
 *  copy, modify, merge, publish, distribute, sublicense, and/or
 *  sell copies of the Software, and to permit persons to whom the
 *  Software is furnished to do so, subject to the following
 *  conditions:
 *
 *  The above copyright notice and this permission notice shall be
 *  included in all copies or substantial portions of the
 *  Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
 *  KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 *  WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 *  PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 *  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 *  OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 *  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include <stdlib.h>
#include <string.h>

#include <sys/time.h>
#include "IntelDeflater.h"

extern "C" {
#include "zlib.h"
#include "zconf.h"
#include "igzip_lib.h"
}

#define DEF_MEM_LEVEL 8
//#define DEBUG
//#define profile

#ifdef DEBUG
#  define DBG(M, ...)  fprintf(stdout, "[DEBUG] (%s %s:%d) " M "\n", __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#else
#  define DBG(M, ...)
#endif

static jfieldID FID_lz_stream;
static jfieldID FID_inputBuffer;
static jfieldID FID_inputBufferLength;
static jfieldID FID_endOfStream;
static jfieldID FID_finished;
static jfieldID FID_level;
//static jfieldID FID_inputBufferOffset;

/**
 *  Cache the Java field IDs. Called once when the native library is loaded.
 */
JNIEXPORT void JNICALL Java_com_intel_gkl_compression_IntelDeflater_initNative
(JNIEnv* env, jclass cls) {
  FID_lz_stream = env->GetFieldID(cls, "lz_stream", "J");
  FID_inputBuffer = env->GetFieldID(cls, "inputBuffer", "[B");
  FID_inputBufferLength = env->GetFieldID(cls, "inputBufferLength", "I");
  FID_endOfStream = env->GetFieldID(cls, "endOfStream", "Z");
  FID_finished = env->GetFieldID(cls, "finished", "Z");
  FID_level = env->GetFieldID(cls,"level","I");
//  FID_inputBufferOffset = env->GetFieldID(cls, "inputBufferOffset", "I");

}

/**
 *  Reset the compressor to prepare for new input data. If the stream structure
 *  does not exists yet, it is allocated.
 */
JNIEXPORT void JNICALL Java_com_intel_gkl_compression_IntelDeflater_resetNative
(JNIEnv* env, jobject obj, jboolean nowrap) {

  jint level = env->GetIntField(obj, FID_level);

  if(level == 1 || level ==2) {
    isal_zstream* lz_stream = (isal_zstream*)env->GetLongField(obj, FID_lz_stream);

    if (lz_stream == 0) {
      lz_stream = (isal_zstream*)malloc(sizeof(isal_zstream));
      if ( lz_stream == NULL ) {
        jclass Exception = env->FindClass("java/lang/Exception");
        env->ThrowNew(Exception,"Memory allocation error");
      }

      env->SetLongField(obj, FID_lz_stream, (jlong)lz_stream);

       isal_deflate_stateless_init(lz_stream);

    lz_stream->level = level;
    lz_stream->level_buf = (uint8_t*)malloc(ISAL_DEF_LVL2_DEFAULT);
    lz_stream->level_buf_size = ISAL_DEF_LVL2_DEFAULT;

    }
    else {

      isal_deflate_stateless_init(lz_stream);

    }

    lz_stream->end_of_stream = 0;

   // DBG("lz_stream = 0x%lx", (long)lz_stream);
  }
  else {

    z_stream* lz_stream = (z_stream*)env->GetLongField(obj, FID_lz_stream);

    if (lz_stream == 0) {
      lz_stream = (z_stream*)calloc(1, sizeof(z_stream));
      if ( lz_stream == NULL ) {
        jclass Exception = env->FindClass("java/lang/Exception");
        env->ThrowNew(Exception,"Memory allocation error");
      }
      env->SetLongField(obj, FID_lz_stream, (jlong)lz_stream);

      lz_stream->zalloc = Z_NULL;
      lz_stream->zfree = Z_NULL;
      lz_stream->opaque = Z_NULL;
      int ret = deflateInit2(lz_stream, level,  Z_DEFLATED,
                             nowrap ? -MAX_WBITS : MAX_WBITS,
                             DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
      if (ret != Z_OK) {
        jclass Exception = env->FindClass("java/lang/Exception");
        env->ThrowNew(Exception,"IntelDeflater init error");
      }
    }
    else {
      deflateReset(lz_stream);
    }

  }
}

/**
* Generate Dynamic Huffman tables
* This function will be called only if we are implementing the fully dynamic huffman implementation which is not set as default in current implementation
* current implementation we use semi-dynamic huffman with tables generated using only first 64k block of stream
*/

JNIEXPORT void JNICALL Java_com_intel_gkl_compression_IntelDeflater_generateHuffman
(JNIEnv * env, jobject obj) {

      jbyteArray inputBuffer = (jbyteArray)env->GetObjectField(obj, FID_inputBuffer);

      jint level = env->GetIntField(obj, FID_level);

      if(level == 1) {
      isal_zstream* lz_stream = (isal_zstream*)env->GetLongField(obj, FID_lz_stream);

      jbyte* input = (jbyte*)env->GetPrimitiveArrayCritical(inputBuffer, 0);

      struct isal_huff_histogram *histogram;
      struct isal_hufftables *hufftables_custom;

      memset(histogram, 0, sizeof(isal_huff_histogram));
      isal_update_histogram((unsigned char*)input, 64*1024, histogram);
      isal_create_hufftables(hufftables_custom, histogram);
      lz_stream->hufftables = hufftables_custom;

      env->SetLongField(obj, FID_lz_stream, (jlong)lz_stream);
      env->ReleasePrimitiveArrayCritical(inputBuffer, input, 0);
      }
}

/**
 *  Deflate the data.
 */
JNIEXPORT jint JNICALL Java_com_intel_gkl_compression_IntelDeflater_deflateNative
(JNIEnv * env, jobject obj, jbyteArray outputBuffer, jint outputBufferLength) {

  jbyteArray inputBuffer = (jbyteArray)env->GetObjectField(obj, FID_inputBuffer);
  jint inputBufferLength = env->GetIntField(obj, FID_inputBufferLength);
  //jint inputBufferOffset = env->GetIntField(obj, FID_inputBufferOffset);
  jboolean endOfStream = env->GetBooleanField(obj, FID_endOfStream);
  jint level = env->GetIntField(obj, FID_level);

  if(level == 1 || level ==2 ) {

    isal_zstream* lz_stream = (isal_zstream*)env->GetLongField(obj, FID_lz_stream);

    isal_zstream stream;

    jbyte* next_in = (jbyte*)env->GetPrimitiveArrayCritical(inputBuffer, 0);
    jbyte* next_out = (jbyte*)env->GetPrimitiveArrayCritical(outputBuffer, 0);

    lz_stream->next_in = (UINT8*)(next_in);
    lz_stream->avail_in = inputBufferLength;
    lz_stream->end_of_stream = endOfStream;
    lz_stream->next_out = (UINT8*) (next_out);
    lz_stream->avail_out = outputBufferLength ;

    int bytes_in = inputBufferLength;

#ifdef profile
    struct timeval  tv1, tv2;
    gettimeofday(&tv1, NULL);
#endif

    // compress and update lz_stream state
    isal_deflate_stateless(lz_stream);

#ifdef profile
    gettimeofday(&tv2, NULL);
    DBG ("Total time = %f seconds\n",
             (double) (tv2.tv_usec - tv1.tv_usec) / 1000000 +
             (double) (tv2.tv_sec - tv1.tv_sec));
#endif

    long bytes_out = outputBufferLength - lz_stream->avail_out;

     DBG ("bytes_out = %d \n", bytes_out);
      DBG ("avail_out = %d \n",lz_stream->avail_out );

    // release buffers
    env->ReleasePrimitiveArrayCritical(inputBuffer, next_in, 0);
    env->ReleasePrimitiveArrayCritical(outputBuffer, next_out, 0);

    // set finished if endOfStream was set and all input processed
    if (endOfStream && lz_stream->avail_in == 0) {
      env->SetBooleanField(obj, FID_finished, true);
    }

    // return number of bytes written to output buffer
    return bytes_out;
  }
  else {

    z_stream* lz_stream = (z_stream*)env->GetLongField(obj, FID_lz_stream);

    jbyte* next_in = (jbyte*)env->GetPrimitiveArrayCritical(inputBuffer, 0);
    jbyte* next_out = (jbyte*)env->GetPrimitiveArrayCritical(outputBuffer, 0);

    lz_stream->next_in = (Bytef *) next_in;
    lz_stream->avail_in = (uInt) inputBufferLength;
    lz_stream->next_out = (Bytef *) next_out;
    lz_stream->avail_out = (uInt) outputBufferLength;

    int bytes_in = inputBufferLength;

#ifdef profile
    struct timeval  tv1, tv2;
    gettimeofday(&tv1, NULL);
#endif
    // compress and update lz_stream state
    int ret = deflate(lz_stream, Z_FINISH);

 #ifdef profile
     gettimeofday(&tv2, NULL);

     DBG ("Total time = %f seconds\n",
              (double) (tv2.tv_usec - tv1.tv_usec) / 1000000 +
              (double) (tv2.tv_sec - tv1.tv_sec));
 #endif

    int bytes_out = outputBufferLength - lz_stream->avail_out;

    // release buffers
    env->ReleasePrimitiveArrayCritical(inputBuffer, next_in, 0);
    env->ReleasePrimitiveArrayCritical(outputBuffer, next_out, 0);

    if (ret == Z_STREAM_END && lz_stream->avail_in == 0) {
      env->SetBooleanField(obj, FID_finished, true);
    }

    return bytes_out;
  }
}

/**
 *  Close the compressor and reclaim memory
 */
JNIEXPORT void JNICALL
Java_com_intel_gkl_compression_IntelDeflater_endNative(JNIEnv *env, jobject obj)
{
  jint level = env->GetIntField(obj, FID_level);
   if (level == 1 || level == 2 ) {
     isal_zstream* lz_stream = (isal_zstream*)env->GetLongField(obj, FID_lz_stream);
      free(lz_stream->level_buf);
      free(lz_stream);

   }
  else {
    z_stream* lz_stream = (z_stream*)env->GetLongField(obj, FID_lz_stream);
    deflateEnd(lz_stream);
    free(lz_stream);
  }

}
<|endoftext|>


<commit_before>#include "cinder/app/App.h"
#include "cinder/app/RendererGl.h"
#include "cinder/gl/gl.h"

// UserInterface
#include "CinderImGui.h"
// Settings
#include "VDSettings.h"
// Session
#include "VDSession.h"
// Log
#include "VDLog.h"
// UI
#include "VDUIAudio.h"

using namespace ci;
using namespace ci::app;
using namespace std;
using namespace VideoDromm;

#define IM_ARRAYSIZE(_ARR)			((int)(sizeof(_ARR)/sizeof(*_ARR)))

class VideodrommAudioApp : public App {

public:
	void setup() override;
	void mouseMove(MouseEvent event) override;
	void mouseDown(MouseEvent event) override;
	void mouseDrag(MouseEvent event) override;
	void mouseUp(MouseEvent event) override;
	void keyDown(KeyEvent event) override;
	void keyUp(KeyEvent event) override;
	void fileDrop(FileDropEvent event) override;
	void update() override;
	void draw() override;
	void cleanup() override;
private:
	// Settings
	VDSettingsRef				mVDSettings;
	// Session
	VDSessionRef				mVDSession;
	// Log
	VDLogRef					mVDLog;
	// UIAudio
	VDUIAudioRef				mUIAudio;

	// handle resizing for imgui
	void						resizeWindow();
	bool						mIsResizing;
	// imgui
	float						color[4];
	float						backcolor[4];
	int							playheadPositions[12];
	int							speeds[12];

	float						f = 0.0f;
	char						buf[64];
	unsigned int				i, j;

	bool						mouseGlobal;

	string						mError;
	// fbo
	bool						mIsShutDown;
};

void VideodrommAudioApp::setup()
{
	// Settings
	mVDSettings = VDSettings::create();
	// Session
	mVDSession = VDSession::create(mVDSettings);
	mVDSession->getWindowsResolution();
	// UIAudio
	mUIAudio = VDUIAudio::create(mVDSettings, mVDSession);
	// set ui window and io events callbacks
	ui::connectWindow(getWindow());
	ui::initialize();

	// windows
	mIsShutDown = false;
	// fps limiting
	setFrameRate(5.0f);
}
void VideodrommAudioApp::fileDrop(FileDropEvent event)
{
	mVDSession->fileDrop(event);
}
void VideodrommAudioApp::update()
{
	mVDSession->update(1);
}
void VideodrommAudioApp::cleanup()
{
	if (!mIsShutDown)
	{
		mIsShutDown = true;
		CI_LOG_V("shutdown");
		ui::disconnectWindow(getWindow());
		ui::Shutdown();
		// save settings
		mVDSettings->save();
		mVDSession->save();
		quit();
	}
}
void VideodrommAudioApp::mouseMove(MouseEvent event)
{
	if (!mVDSession->handleMouseMove(event)) {
		// let your application perform its mouseMove handling here
	}
}
void VideodrommAudioApp::mouseDown(MouseEvent event)
{
	if (!mVDSession->handleMouseDown(event)) {
		// let your application perform its mouseDown handling here
	}
}
void VideodrommAudioApp::mouseDrag(MouseEvent event)
{
	if (!mVDSession->handleMouseDrag(event)) {
		// let your application perform its mouseDrag handling here
	}
}
void VideodrommAudioApp::mouseUp(MouseEvent event)
{
	if (!mVDSession->handleMouseUp(event)) {
		// let your application perform its mouseUp handling here
	}
}

void VideodrommAudioApp::keyDown(KeyEvent event)
{
	if (!mVDSession->handleKeyDown(event)) {
		switch (event.getCode()) {
		case KeyEvent::KEY_ESCAPE:
			// quit the application
			quit();
			break;

		}
	}
}
void VideodrommAudioApp::keyUp(KeyEvent event)
{
	if (!mVDSession->handleKeyUp(event)) {
	}
}
void VideodrommAudioApp::resizeWindow()
{
	mVDSession->resize();
}

void VideodrommAudioApp::draw()
{
	gl::clear(Color::black());

	//gl::setMatricesWindow(toPixels(getWindowSize()),false);
	//gl::setMatricesWindow(mVDSettings->mRenderWidth, mVDSettings->mRenderHeight, false);
	//gl::draw(mVDSession->getMixTexture(), getWindowBounds());
	getWindow()->setTitle(toString((int)getAverageFps()) + " fps Videodromm");
	// imgui
	if (!mVDSettings->mCursorVisible) return;

	mUIAudio->Run("Audio");

}

CINDER_APP(VideodrommAudioApp, RendererGl)
<commit_msg>audio wip<commit_after>#include "cinder/app/App.h"
#include "cinder/app/RendererGl.h"
#include "cinder/gl/gl.h"

// UserInterface
#include "CinderImGui.h"
// Settings
#include "VDSettings.h"
// Session
#include "VDSession.h"
// Log
#include "VDLog.h"
// UI
#include "VDUIAudio.h"

using namespace ci;
using namespace ci::app;
using namespace std;
using namespace VideoDromm;

#define IM_ARRAYSIZE(_ARR)			((int)(sizeof(_ARR)/sizeof(*_ARR)))

class VideodrommAudioApp : public App {

public:
	void setup() override;
	void mouseMove(MouseEvent event) override;
	void mouseDown(MouseEvent event) override;
	void mouseDrag(MouseEvent event) override;
	void mouseUp(MouseEvent event) override;
	void keyDown(KeyEvent event) override;
	void keyUp(KeyEvent event) override;
	void fileDrop(FileDropEvent event) override;
	void update() override;
	void draw() override;
	void cleanup() override;
private:
	// Settings
	VDSettingsRef				mVDSettings;
	// Session
	VDSessionRef				mVDSession;
	// Log
	VDLogRef					mVDLog;
	// UIAudio
	VDUIAudioRef				mUIAudio;
	// handle resizing for imgui
	void						resizeWindow();
	bool						mIsResizing;
	// imgui
	float						color[4];
	float						backcolor[4];
	int							playheadPositions[12];
	int							speeds[12];

	float						f = 0.0f;
	char						buf[64];
	unsigned int				i, j;

	bool						mouseGlobal;

	string						mError;
	// fbo
	bool						mIsShutDown;
};

void VideodrommAudioApp::setup()
{
	// Settings
	mVDSettings = VDSettings::create();
	// Session
	mVDSession = VDSession::create(mVDSettings);
	mVDSession->getWindowsResolution();
	// UIAudio
	mUIAudio = VDUIAudio::create(mVDSettings, mVDSession);
	// set ui window and io events callbacks
	ui::connectWindow(getWindow());
	ui::initialize();

	// windows
	mIsShutDown = false;
	// fps limiting
	setFrameRate(5.0f);
}
void VideodrommAudioApp::fileDrop(FileDropEvent event)
{
	mVDSession->fileDrop(event);
}
void VideodrommAudioApp::update()
{
	mVDSession->update(1);
}
void VideodrommAudioApp::cleanup()
{
	if (!mIsShutDown)
	{
		mIsShutDown = true;
		CI_LOG_V("shutdown");
		ui::disconnectWindow(getWindow());
		ui::Shutdown();
		// save settings
		mVDSettings->save();
		mVDSession->save();
		quit();
	}
}
void VideodrommAudioApp::mouseMove(MouseEvent event)
{
	if (!mVDSession->handleMouseMove(event)) {
		// let your application perform its mouseMove handling here
	}
}
void VideodrommAudioApp::mouseDown(MouseEvent event)
{
	if (!mVDSession->handleMouseDown(event)) {
		// let your application perform its mouseDown handling here
	}
}
void VideodrommAudioApp::mouseDrag(MouseEvent event)
{
	if (!mVDSession->handleMouseDrag(event)) {
		// let your application perform its mouseDrag handling here
	}
}
void VideodrommAudioApp::mouseUp(MouseEvent event)
{
	if (!mVDSession->handleMouseUp(event)) {
		// let your application perform its mouseUp handling here
	}
}

void VideodrommAudioApp::keyDown(KeyEvent event)
{
	if (!mVDSession->handleKeyDown(event)) {
		switch (event.getCode()) {
		case KeyEvent::KEY_ESCAPE:
			// quit the application
			quit();
			break;

		}
	}
}
void VideodrommAudioApp::keyUp(KeyEvent event)
{
	if (!mVDSession->handleKeyUp(event)) {
	}
}
void VideodrommAudioApp::resizeWindow()
{
	mVDSession->resize();
}

void VideodrommAudioApp::draw()
{
	gl::clear(Color::black());

	getWindow()->setTitle(toString((int)getAverageFps()) + " fps Videodromm");
	// imgui
	if (!mVDSettings->mCursorVisible) return;

	mUIAudio->Run("Audio");

}

CINDER_APP(VideodrommAudioApp, RendererGl)
<|endoftext|>


<commit_before>// -*- Mode:C++ -*-

/**************************************************************************************************/
/*                                                                                */
/* Copyright (C) 2014 University of Hull                                                          */
/*                                                                                */
/**************************************************************************************************/
/*                                                                                */
/*  module     :  projection/main.cpp                                                             */
/*  project    :                                                                                */
/*  description:                                                                                */
/*                                                                                */
/**************************************************************************************************/

// includes, system

#include <cstdlib> // EXIT_SUCCESS

// includes, project

//#include <>

#define UKACHULLDCS_USE_TRACE
#undef UKACHULLDCS_USE_TRACE
#include <support/trace.hpp>

// internal unnamed namespace

namespace {

  // types, internal (class, enum, struct, union, typedef)

  // variables, internal

  // functions, internal

} // namespace {

int
main(int /* argc */, char* /* argv */[])
{
  return EXIT_SUCCESS;
}
<commit_msg>added: implementation<commit_after>// -*- Mode:C++ -*-

/**************************************************************************************************/
/*                                                                                */
/* Copyright (C) 2014 University of Hull                                                          */
/*                                                                                */
/**************************************************************************************************/
/*                                                                                */
/*  module     :  projection/main.cpp                                                             */
/*  project    :                                                                                */
/*  description:                                                                                */
/*                                                                                */
/**************************************************************************************************/

// includes, system

#include <array>                        // std::array<>
#include <boost/concept_check.hpp>      // boost::ignore_unused_variable_warning<>
#include <cstdlib>                      // EXIT_SUCCESS
#if defined(_WIN32)
#  include <directxmath.h>              // XMMatrixPerspectiveLH
#endif
#include <glm/gtc/matrix_transform.hpp> // glm::[frustum,perspective]
#include <glm/gtx/io.hpp>               // glm::operator<<
#include <glm/gtx/transform.hpp>        // glm::[rotate,scale,translate]
#include <iostream>                     // std::cout
#include <sstream>                      // std::ostringstream

// includes, project

#include <glm/gtx/utilities.hpp>

#define UKACHULLDCS_USE_TRACE
#undef UKACHULLDCS_USE_TRACE
#include <support/trace.hpp>

// internal unnamed namespace

namespace {

  // types, internal (class, enum, struct, union, typedef)

  struct frustum_t  { float l, r, b, t,  n,  f; };
  struct viewport_t { float x, y, w, h, dn, df; };

  // variables, internal

  // functions, internal

  std::ostream&
  operator<<(std::ostream& os, frustum_t const& a)
  {
    std::ostream::sentry const cerberus(os);

    if (cerberus) {
      os << '[' << "l:" << a.l << ',' << "r:" << a.r << ',' << "b:" << a.b << ','
         << "t:" << a.t << ',' << "n:" << a.n << ',' << "f:" << a.f << ']';
    }

    return os;
  }

  std::ostream&
  operator<<(std::ostream& os, viewport_t const& a)
  {
    std::ostream::sentry const cerberus(os);

    if (cerberus) {
      os << '[' << "x:"  << a.x  << ',' << "y:"  << a.y  << ',' << "w:"  << a.w  << ','
         << "h:"  << a.h  << ',' << "dn:" << a.dn << ',' << "df:" << a.df << ']';
    }

    return os;
  }

  std::string
  pipeline_result(glm::vec3 const& obj, glm::vec4 const& clp, glm::vec3 const& ndc,
                  glm::vec3 const& wc)
  {
    std::ostringstream ostr;

    ostr << glm::io::precision(3) << glm::io::width(1 + 3 + 1 + 3)
         << "obj:" << obj << " -> "
         << "clp:" << clp << " -> "
         << "ndc:" << ndc << " -> "
         << "wc:"  << wc;

    return ostr.str();
  }

} // namespace {

namespace ogl {

  glm::vec4
  eye_to_clip(glm::vec3 const& p, glm::mat4 const& m)
  {
    return (m * glm::vec4(p, 1.0));
  }

  glm::vec3
  clip_to_ndc(glm::vec4 const& p)
  {
    return glm::vec3(p.x / p.w, p.y / p.w, p.z / p.w);
  }

  glm::vec3
  ndc_to_wc(glm::vec3 const& p, viewport_t const& v)
  {
    glm::vec3 result;

#if 0
    // glspec43.core20120806:13.6.1
    result.x  = ((p.x + 1) * (v.w / 2.0f))      +                    v.x;
    result.y  = ((p.y + 1) * (v.h / 2.0f))      +                    v.y;
    result.z  =  (p.z * ((v.df - v.dn) / 2.0f)) + ((v.dn + v.df) / 2.0f);
#else
    // assuming v.df:1 and v.dn:0
    result    = p * 0.5f + 0.5f;
    result.x *= v.w + v.x;
    result.y *= v.h + v.y;
#endif

    return result;
  }

  std::string
  pipeline(glm::vec3 const& p, glm::mat4 const& mvp, viewport_t const& vp)
  {
    glm::vec3 const cs_obj(p);
    glm::vec4 const cs_clp(eye_to_clip(cs_obj, mvp));
    glm::vec3 const cs_ndc(clip_to_ndc(cs_clp));
    glm::vec3 const cs_wc (ndc_to_wc  (cs_ndc, vp));

    return pipeline_result(cs_obj, cs_clp, cs_ndc, cs_wc);
  }

} // namespace ogl {

namespace d3d {

  using ogl::eye_to_clip;
  using ogl::clip_to_ndc;

  glm::vec3
  ndc_to_wc(glm::vec3 const& p, viewport_t const& v)
  {
    glm::vec3 result;

    // http://msdn.microsoft.com/en-us/library/windows/desktop/bb205126%28v=vs.85%29.aspx
    result.x = ((p.x + 1) * (v.w / 2.0f)) + v.x;
    result.y = ((1 - p.y) * (v.h / 2.0f)) + v.y;
    result.z = ( p.z * (v.df - v.dn))     + v.dn;

    return result;
  }

  std::string
  pipeline(glm::vec3 const& p, glm::mat4 const& mvp, viewport_t const& vp)
  {
    glm::vec3 const cs_obj(p);
    glm::vec4 const cs_clp(eye_to_clip(cs_obj, mvp));
    glm::vec3 const cs_ndc(clip_to_ndc(cs_clp));
    glm::vec3 const cs_wc (ndc_to_wc  (cs_ndc, vp));

    return pipeline_result(cs_obj, cs_clp, cs_ndc, cs_wc);
  }

} // namespace d3d {

namespace {

  // types, internal (class, enum, struct, union, typedef)

  typedef std::pair<glm::mat4 const, glm::mat4 const> matrix_pair;

  // variables, internal

  float const      fov(80.0);
  viewport_t const viewport = { 0, 0, 500, 500, 0,     1    };
  frustum_t const  frustum  = {-1, 1,  -1,   1, 0.1f, 10.0f };

  std::array<glm::vec3, 3> const box = {
    {
      glm::vec3( 0.0,  0.0,  0.0),
      //glm::vec3(-0.5, -0.5,  0.5),
      //glm::vec3( 0.5, -0.5,  0.5),
      glm::vec3( 0.5,  0.5,  0.5),
      //glm::vec3(-0.5,  0.5,  0.5),
      glm::vec3(-0.5, -0.5, -0.5),
      //glm::vec3( 0.5, -0.5, -0.5),
      //glm::vec3( 0.5,  0.5, -0.5),
      //glm::vec3(-0.5,  0.5, -0.5),
    }
  };

  glm::mat4 const camera_view(glm::lookAt(glm::vec3(0,1.8,3),
                                          glm::vec3(0,0,0),
                                          glm::vec3(0,1,0)));

  // functions, internal

  void
  test_ogl_native(glm::mat4 const& model, glm::mat4 const& view, bool terse)
  {
    glm::mat4 const proj1(glm::frustum(frustum.l, frustum.r, frustum.b, frustum.t,
                                       frustum.n, frustum.f));
    glm::mat4 const proj2(glm::perspective(fov, (viewport.w / viewport.h), frustum.n, frustum.f));
    glm::mat4 const mvp1 (proj1 * view * model);
    glm::mat4 const mvp2 (proj2 * view * model);

    matrix_pair const view_pair(std::make_pair(camera_view, view));
    matrix_pair const proj_pair(std::make_pair(proj1, proj2));
    matrix_pair const mvp_pair (std::make_pair(mvp1, mvp2));

    std::cout << '\n'
              << "OGL native"
              << '\n';

    if (!terse) {
      std::cout << "frustum :"                           << frustum   << ' '
                << "viewport:"                           << viewport  << '\n'
                << "model:"                              << model     << '\n'
                << "view: camera/view"                   << view_pair << '\n'
                << "proj: glm::frustum/glm::perspective" << proj_pair << '\n'
                << "mvp: glm::frustum/glm::perspective"  << mvp_pair  << '\n';
    }

    std::cout << std::string(159, '-') << '\n';

    for (auto const& c : box) {
      std::cout << "OGL:frust: " << ogl::pipeline(c, mvp1, viewport) << '\n'
                << "OGL:persp: " << ogl::pipeline(c, mvp2, viewport) << '\n';

      if (*(box.rbegin()) != c) {
        std::cout << '\n';
      }
    }

    std::cout << std::string(159, '-') << '\n';
  }

  void
  test_d3d_native(glm::mat4 const& model, glm::mat4 const& view, bool terse)
  {
#if defined(_WIN32)
    glm::mat4 const proj1;
    {
      using namespace DirectX;

      XMMATRIX const xmmat(XMMatrixPerspectiveFovLH(glm::radians(fov),
                                                    (viewport.w / viewport.h),
                                                    frustum.n, frustum.f));
      XMFLOAT4X4     xmflt;

      XMStoreFloat4x4(&xmflt, xmmat);

      proj1 = glm::mat4(xmflt._11, xmflt._12, xmflt._13, xmflt._14,
                        xmflt._21, xmflt._22, xmflt._23, xmflt._24,
                        xmflt._31, xmflt._32, xmflt._33, xmflt._34,
                        xmflt._41, xmflt._42, xmflt._43, xmflt._44);
      proj1 *= glm::scale(1.0f,1.0f,-1.0f);
    }
    glm::mat4 const proj2;
    {
      using namespace DirectX;

      XMMATRIX const xmmat(XMMatrixPerspectiveFovRH(glm::radians(fov),
                                                    (viewport.w / viewport.h),
                                                    frustum.n, frustum.f));
      XMFLOAT4X4     xmflt;

      XMStoreFloat4x4(&xmflt, xmmat);

      proj2 = glm::mat4(xmflt._11, xmflt._12, xmflt._13, xmflt._14,
                        xmflt._21, xmflt._22, xmflt._23, xmflt._24,
                        xmflt._31, xmflt._32, xmflt._33, xmflt._34,
                        xmflt._41, xmflt._42, xmflt._43, xmflt._44);
    }
    glm::mat4 const mvp1 (proj1 * view * model);
    glm::mat4 const mvp2 (proj2 * view * model);

    matrix_pair const view_pair(std::make_pair(camera_view, view));
    matrix_pair const proj_pair(std::make_pair(proj1, proj2));
    matrix_pair const mvp_pair (std::make_pair(mvp1, mvp2));

    std::cout << '\n'
              << "D3D native"
              << '\n';

    if (!terse) {
      std::cout << "frustum :"                           << frustum   << ' '
                << "viewport:"                           << viewport  << '\n'
                << "model:"                              << model     << '\n'
                << "view: camera/view"                   << view_pair << '\n'
                << "proj: glm::frustum/glm::perspective" << proj_pair << '\n'
                << "mvp: glm::frustum/glm::perspective"  << mvp_pair  << '\n';
    }

    std::cout << std::string(159, '-') << '\n';

    for (auto const& c : box) {
      std::cout << "D3D:frust: " << ogl::pipeline(c, mvp1, viewport) << '\n'
                << "D3D:persp: " << ogl::pipeline(c, mvp2, viewport) << '\n';

      if (*(box.rbegin()) != c) {
        std::cout << '\n';
      }
    }

    std::cout << std::string(159, '-') << '\n';
#else
    boost::ignore_unused_variable_warning(model);
    boost::ignore_unused_variable_warning(view);
    boost::ignore_unused_variable_warning(terse);
#endif
  }

  void
  test_ogl_over_d3d_proj(glm::mat4 const& model, glm::mat4 const& view, bool terse)
  {
    glm::mat4 const proj1(glm::convert::opengl_to_d3d *
                          glm::frustum(frustum.l, frustum.r, frustum.b, frustum.t,
                                       frustum.n, frustum.f));
    glm::mat4 const proj2(glm::convert::opengl_to_d3d *
                          glm::perspective(fov, (viewport.w / viewport.h), frustum.n, frustum.f));
    glm::mat4 const mvp1 (proj1 * view * model);
    glm::mat4 const mvp2 (proj2 * view * model);

    matrix_pair const view_pair(std::make_pair(camera_view, view));
    matrix_pair const proj_pair(std::make_pair(proj1, proj2));
    matrix_pair const mvp_pair (std::make_pair(mvp1, mvp2));

    std::cout << '\n'
              << "OGL over D3D (projective)"
              << '\n';

    if (!terse) {
      std::cout << "frustum :"                           << frustum   << ' '
                << "viewport:"                           << viewport  << '\n'
                << "model:"                              << model     << '\n'
                << "view: camera/view"                   << view_pair << '\n'
                << "proj: glm::frustum/glm::perspective" << proj_pair << '\n'
                << "mvp: glm::frustum/glm::perspective"  << mvp_pair  << '\n';
    }

    std::cout << std::string(159, '-') << '\n';

    for (auto const& c : box) {
      std::cout << "D3D:frust: " << d3d::pipeline(c, mvp1, viewport) << '\n'
                << "D3D:persp: " << d3d::pipeline(c, mvp2, viewport) << '\n';

      if (*(box.rbegin()) != c) {
        std::cout << '\n';
      }
    }

    std::cout << std::string(159, '-') << '\n';
  }

  void
  test_ogl_over_d3d_ortho(glm::mat4 const& model, glm::mat4 const& view, bool terse)
  {
    glm::mat4 const proj1(glm::ortho(frustum.l, frustum.r, frustum.b, frustum.t,
                                     frustum.n, frustum.f));
    glm::mat4 const proj2(glm::convert::opengl_to_d3d * proj1);
    glm::mat4 const mvp1 (proj1 * view * model);
    glm::mat4 const mvp2 (proj2 * view * model);

    matrix_pair const view_pair(std::make_pair(camera_view, view));
    matrix_pair const proj_pair(std::make_pair(proj1, proj2));
    matrix_pair const mvp_pair (std::make_pair(mvp1, mvp2));

    std::cout << '\n'
              << "OGL over D3D (orthographic)"
              << '\n';

    if (!terse) {
      std::cout << "frustum :"                           << frustum   << ' '
                << "viewport:"                           << viewport  << '\n'
                << "model:"                              << model     << '\n'
                << "view: camera/view"                   << view_pair << '\n'
                << "proj: glm::frustum/glm::perspective" << proj_pair << '\n'
                << "mvp: glm::frustum/glm::perspective"  << mvp_pair  << '\n';
    }

    std::cout << std::string(159, '-') << '\n';

    for (auto const& c : box) {
      std::cout << "OGL:ortho: " << ogl::pipeline(c, mvp1, viewport) << '\n'
                << "D3D:ortho: " << d3d::pipeline(c, mvp2, viewport) << '\n';

      if (*(box.rbegin()) != c) {
        std::cout << '\n';
      }
    }

    std::cout << std::string(159, '-') << '\n';
  }

} // namespace {

int
main(int argc, char* /* argv */[])
{
  glm::mat4 const model(glm::scale(glm::vec3(0.9f, 0.9f, 0.9f)));
  glm::mat4 const view (camera_view);
  bool            terse(true);

  if (2 <= argc) {
    terse = false;
  }

  test_ogl_native        (model, view, terse);
  test_d3d_native        (model, view, terse);
  test_ogl_over_d3d_proj (model, view, terse);
  test_ogl_over_d3d_ortho(model, view, terse);

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>
#include "Common.hpp"
#include "helpers/GenerationUtilities.hpp"
#include "input/Input.hpp"
#include "helpers/InterfaceUtilities.hpp"
#include "resources/ResourcesManager.hpp"
#include "Game.hpp"

/**
 \defgroup SnakeGame Snake Game
 \brief A small 3D game demo.
 \ingroup Applications
 */

/**
 The main function of the game demo. Handles the setup and main loop.
 \param argc the number of input arguments.
 \param argv a pointer to the raw input arguments.
 \return a general error code.
 \ingroup SnakeGame
 */
int main(int argc, char** argv) {

	// First, init/parse/load configuration.
	RenderingConfig config(argc, argv);
	config.initialWidth = 800;
	config.initialHeight = 600;
	config.forceAspectRatio = true;

	GLFWwindow* window = Interface::initWindow("SnakeGame", config);
	if(!window){
		return -1;
	}

	Resources::manager().addResources("../../../resources/snakegame");
	// Initialize random generator;
	Random::seed();

	// Create the game main handler..
	Game game(config);

	double timer = glfwGetTime();
	double fullTime = 0.0;
	double remainingTime = 0.0;
	const double dt = 1.0/120.0; // Small physics timestep.

	// Start the display/interaction loop.
	while (!glfwWindowShouldClose(window)) {
		// Update events (inputs,...).
		Input::manager().update();

		// Start a new frame for the interface.
		Interface::beginFrame();

		// We separate punctual events from the main physics/movement update loop.
		const Interface::Action actionToTake = game.update();
		if(actionToTake != Interface::Action::None){
			Interface::performWindowAction(window, config, actionToTake);
			// Due to the ordering between the update function and the fullscreen activation, we have to manually call resize here.
			// Another solution would be to check resizing before rendering, in the Game object.
			if(actionToTake == Interface::Action::Fullscreen){
				game.resize((unsigned int)Input::manager().size()[0], (unsigned int)Input::manager().size()[1]);
			}
		}

		// Compute the time elapsed since last frame
		double currentTime = glfwGetTime();
		double frameTime = currentTime - timer;
		timer = currentTime;

		// Physics simulation
		// First avoid super high frametime by clamping.
		if(frameTime > 0.2){ frameTime = 0.2; }
		// Accumulate new frame time.
		remainingTime += frameTime;
		// Instead of bounding at dt, we lower our requirement (1 order of magnitude).
		while(remainingTime > 0.2*dt){
			double deltaTime = fmin(remainingTime, dt);
			// Update physics and camera.
			game.physics(fullTime, deltaTime);
			// Update timers.
			fullTime += deltaTime;
			remainingTime -= deltaTime;
		}

		// Update the content of the window.
		game.draw();
		// Then render the interface.
		Interface::endFrame();
		//Display the result for the current rendering loop.
		glfwSwapBuffers(window);

	}

	// Clean the interface.
	Interface::clean();
	// Remove the window.
	glfwDestroyWindow(window);
	// Clean other resources
	game.clean();
	// Close GL context and any other GLFW resources.
	glfwTerminate();

	return 0;
}

<commit_msg>Snake: save config to disk and restore it at launch.<commit_after>
#include "Common.hpp"
#include "helpers/GenerationUtilities.hpp"
#include "input/Input.hpp"
#include "helpers/InterfaceUtilities.hpp"
#include "resources/ResourcesManager.hpp"
#include "Game.hpp"

/**
 \defgroup SnakeGame Snake Game
 \brief A small 3D game demo.
 \ingroup Applications
 */

/**
 The main function of the game demo. Handles the setup and main loop.
 \param argc the number of input arguments.
 \param argv a pointer to the raw input arguments.
 \return a general error code.
 \ingroup SnakeGame
 */
int main(int argc, char** argv) {

	// First, init/parse/load configuration.
	const std::vector<std::string> forceArgv = {"SnakeGame", "-c", "config.ini"};
	RenderingConfig config(forceArgv);
	config.initialWidth = 800;
	config.initialHeight = 600;
	config.forceAspectRatio = true;

	GLFWwindow* window = Interface::initWindow("SnakeGame", config);
	if(!window){
		return -1;
	}

	Resources::manager().addResources("../../../resources/snakegame");
	// Initialize random generator;
	Random::seed();

	// Create the game main handler..
	Game game(config);

	double timer = glfwGetTime();
	double fullTime = 0.0;
	double remainingTime = 0.0;
	const double dt = 1.0/120.0; // Small physics timestep.

	// Start the display/interaction loop.
	while (!glfwWindowShouldClose(window)) {
		// Update events (inputs,...).
		Input::manager().update();

		// Start a new frame for the interface.
		Interface::beginFrame();

		// We separate punctual events from the main physics/movement update loop.
		const Interface::Action actionToTake = game.update();
		if(actionToTake != Interface::Action::None){
			Interface::performWindowAction(window, config, actionToTake);
			// Due to the ordering between the update function and the fullscreen activation, we have to manually call resize here.
			// Another solution would be to check resizing before rendering, in the Game object.
			if(actionToTake == Interface::Action::Fullscreen){
				game.resize((unsigned int)Input::manager().size()[0], (unsigned int)Input::manager().size()[1]);
			}
			// Update the config on disk, for next launch.
			Resources::saveStringToExternalFile("./config.ini", "# SnakeGame Config v1.0\n" + std::string(config.fullscreen ? "fullscreen\n" : "") + (!config.vsync ? "no-vsync" : "\n"));
		}

		// Compute the time elapsed since last frame
		double currentTime = glfwGetTime();
		double frameTime = currentTime - timer;
		timer = currentTime;

		// Physics simulation
		// First avoid super high frametime by clamping.
		if(frameTime > 0.2){ frameTime = 0.2; }
		// Accumulate new frame time.
		remainingTime += frameTime;
		// Instead of bounding at dt, we lower our requirement (1 order of magnitude).
		while(remainingTime > 0.2*dt){
			double deltaTime = fmin(remainingTime, dt);
			// Update physics and camera.
			game.physics(fullTime, deltaTime);
			// Update timers.
			fullTime += deltaTime;
			remainingTime -= deltaTime;
		}

		// Update the content of the window.
		game.draw();
		// Then render the interface.
		Interface::endFrame();
		//Display the result for the current rendering loop.
		glfwSwapBuffers(window);

	}

	// Clean the interface.
	Interface::clean();
	// Remove the window.
	glfwDestroyWindow(window);
	// Clean other resources
	game.clean();
	// Close GL context and any other GLFW resources.
	glfwTerminate();

	return 0;
}

<|endoftext|>


<commit_before>// augmentation_widget.cpp

#include "augmentation_widget.hpp"

#include <QOpenGLExtraFunctions>
#include <QTemporaryFile>
#include <QVector2D>
#include <QVector3D>
#include <math.h>

augmentation_widget::augmentation_widget (QWidget* parent)
: QOpenGLWidget (parent)
, _scale_factor (1.0f)
, _x_pos (0.0f)
, _y_pos (0.0f)
, _opengl_mutex (QMutex::Recursive)
, _last_handle (0)
, _vertex_count (0) {
}

augmentation_widget::~augmentation_widget () {
    _opengl_mutex.lock ();
    glDeleteBuffers (1, &_object_vbo);
    glDeleteVertexArrays (1, &_object_vao);
    _opengl_mutex.unlock ();
}

QSize augmentation_widget::minimumSizeHint () const {
    return QSize (600, 350);
}

QSize augmentation_widget::sizeHint () const {
    return QSize (600, 350);
}

bool augmentation_widget::loadObject (const QString& resource_path) {
    _opengl_mutex.lock ();
    bool status = false;

    // extract model from resources into filesystem and parse it
    QFile resource_file (resource_path);
    if (resource_file.exists ()) {
        auto temp_file  = QTemporaryFile::createNativeFile (resource_file);
        QString fs_path = temp_file->fileName ();

        if (!fs_path.isEmpty ()) {
            std::vector<float> model_interleaved = _object.load (fs_path.toStdString ());

            glBindBuffer (GL_ARRAY_BUFFER, _object_vbo);
            glBufferData (GL_ARRAY_BUFFER, sizeof (float) * model_interleaved.size (),
            model_interleaved.data (), GL_STATIC_DRAW);
            glBindBuffer (GL_ARRAY_BUFFER, 0);
            _vertex_count = model_interleaved.size () / _object.data_per_vertex ();
            _object.release ();

            status = true;
        }
    }
    _opengl_mutex.unlock ();
    return status;
}

void augmentation_widget::downloadImage (image_t& image, GLuint handle) {
    _opengl_mutex.lock ();

    QOpenGLContext* ctx = QOpenGLContext::currentContext ();
    QOpenGLFunctions* f = ctx->functions ();
    GLuint fbo;
    f->glGenFramebuffers (1, &fbo);
    GLuint prevFbo;
    f->glGetIntegerv (GL_FRAMEBUFFER_BINDING, (GLint*)&prevFbo);
    f->glBindFramebuffer (GL_FRAMEBUFFER, fbo);
    f->glFramebufferTexture2D (
    GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, handle, 0);
    f->glReadPixels (
    0, 0, image.width, image.height, GL_RGBA, GL_UNSIGNED_BYTE, image.data);
    f->glBindFramebuffer (GL_FRAMEBUFFER, prevFbo);

    _opengl_mutex.unlock ();
}

void augmentation_widget::setBackground (GLuint tex) {
    // TODO: this might not be the "nicest" way to do this, since it simply
    // ignores the previously generated texture. That texture will be lost,
    // although this only happens once per runtime, so its not THAT bad.
    _opengl_mutex.lock ();
    _texture_background = tex;
    _opengl_mutex.unlock ();
}

void augmentation_widget::setBackground (image_t image) {
    bool status = true;
    GLint format_gl;

    _opengl_mutex.lock ();
    // create background texture
    glBindTexture (GL_TEXTURE_2D, _texture_background);

    switch (image.format) {
        case RGB24: {
            format_gl = GL_RGB;
            break;
        }
        case YUV:
        case GREY8:
        case BINARY8: {
            format_gl = GL_LUMINANCE;
            break;
        }
        case BGR32: {
            status = false;
            break;
        }
    }

    if (status) {
        glTexImage2D (GL_TEXTURE_2D, 0, format_gl, image.width, image.height, 0,
        format_gl, GL_UNSIGNED_BYTE, image.data);
    }
    glBindTexture (GL_TEXTURE_2D, 0);
    _opengl_mutex.unlock ();
}

void augmentation_widget::setScale (const float scale) {
    _opengl_mutex.lock ();
    _scale_factor = scale;
    _opengl_mutex.unlock ();
}

void augmentation_widget::setXPosition (const float location) {
    _opengl_mutex.lock ();
    _x_pos = location;
    _opengl_mutex.unlock ();
}

void augmentation_widget::setYPosition (const float location) {
    _opengl_mutex.lock ();
    _y_pos = location;
    _opengl_mutex.unlock ();
}

void augmentation_widget::setXRotation (const GLfloat angle) {
    _opengl_mutex.lock ();
    _x_rot = -angle;
    _opengl_mutex.unlock ();
}

void augmentation_widget::setYRotation (const GLfloat angle) {
    _opengl_mutex.lock ();
    _y_rot = -angle;
    _opengl_mutex.unlock ();
}

void augmentation_widget::setZRotation (const GLfloat angle) {
    _opengl_mutex.lock ();
    _z_rot = -angle;
    _opengl_mutex.unlock ();
}

void augmentation_widget::initializeGL () {
    _opengl_mutex.lock ();
    initializeOpenGLFunctions ();

    glClearColor (1, 0.5, 1, 1.0f);
    glEnable (GL_DEPTH_TEST);
    // glEnable (GL_CULL_FACE);
    glEnable (GL_TEXTURE_2D);

    glGenTextures (1, &_texture_background);
    glBindTexture (GL_TEXTURE_2D, _texture_background);
    glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glBindTexture (GL_TEXTURE_2D, 0);

    // generate a buffer to bind to textures
    glGenFramebuffers (1, &_readback_buffer);

    // compile and link shaders
    compile_shaders ();

    // generate vertex array buffers
    generate_buffers ();

    // setup projection matrix
    _mat_projection.ortho (-2.0f, +2.0f, -2.0f, +2.0f, 1.0f, 25.0f);

    emit initialized ();
    _opengl_mutex.unlock ();
}

void augmentation_widget::generate_buffers () {
    _opengl_mutex.lock ();
    // setup background vao
    {
        glGenVertexArrays (1, &_background_vao);
        glGenBuffers (1, &_background_vbo);

        glBindVertexArray (_background_vao);
        glBindBuffer (GL_ARRAY_BUFFER, _background_vbo);

        int pos_location = _program_background.attributeLocation ("position");
        glVertexAttribPointer (pos_location, 2, GL_FLOAT, GL_FALSE,
        4 * sizeof (float), reinterpret_cast<void*> (0));
        glEnableVertexAttribArray (pos_location);

        int tex_location = _program_background.attributeLocation ("tex");
        glVertexAttribPointer (tex_location, 2, GL_FLOAT, GL_FALSE,
        4 * sizeof (float), reinterpret_cast<void*> (2 * sizeof (float)));
        glEnableVertexAttribArray (tex_location);

        // fill buffer with data
        GLfloat interleaved_background_buff[6 * 4] = {
            -1.0, 1.0,  // poly 1 a
            0.0, 0.0,   // poly 1 a tex
            -1.0, -1.0, // poly 1 b
            0.0, 1.0,   // poly 1 b tex
            1.0, 1.0,   // poly 1 c
            1.0, 0.0,   // poly 1 c tex
            1.0, 1.0,   // poly 2 a
            1.0, 0.0,   // poly 2 a tex
            -1.0, -1.0, // poly 2 b
            0.0, 1.0,   // poly 2 b tex
            1.0, -1.0,  // poly 2 c
            1.0, 1.0    // poly 2 c tex
        };
        glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 6 * 4,
        interleaved_background_buff, GL_STATIC_DRAW);

        // bind texture
        int tex_uniform =
        _program_background.uniformLocation ("u_tex_background");
        glActiveTexture (GL_TEXTURE0);
        glBindTexture (GL_TEXTURE_2D, _texture_background);
        glUniform1i (tex_uniform, 0);
        glBindTexture (GL_TEXTURE_2D, 0);
    }

    // setup object vao
    {
        glGenVertexArrays (1, &_object_vao);
        glGenBuffers (1, &_object_vbo);

        glBindVertexArray (_object_vao);
        glBindBuffer (GL_ARRAY_BUFFER, _object_vbo);

        int pos_location = _program_object.attributeLocation ("position");
        glVertexAttribPointer (pos_location, 3, GL_FLOAT, GL_FALSE,
        10 * sizeof (float), reinterpret_cast<void*> (0));
        glEnableVertexAttribArray (pos_location);

        int nor_location = _program_object.attributeLocation ("normal");
        glVertexAttribPointer (nor_location, 3, GL_FLOAT, GL_FALSE,
        10 * sizeof (float), reinterpret_cast<void*> (3 * sizeof (float)));
        glEnableVertexAttribArray (nor_location);

        int col_location = _program_object.attributeLocation ("color");
        glVertexAttribPointer (col_location, 4, GL_FLOAT, GL_FALSE,
        10 * sizeof (float), reinterpret_cast<void*> (6 * sizeof (float)));
        glEnableVertexAttribArray (col_location);

        glBindBuffer (GL_ARRAY_BUFFER, 0);
        glBindVertexArray (0);
    }
    _opengl_mutex.unlock ();
}

void augmentation_widget::compile_shaders () {
    _opengl_mutex.lock ();
    // background shaders
    {
        QFile vs_file (":/GL_shaders/background_vs.glsl");
        QFile fs_file (":/GL_shaders/background_fs.glsl");
        vs_file.open (QIODevice::ReadOnly);
        fs_file.open (QIODevice::ReadOnly);
        QByteArray vs_source = vs_file.readAll ();
        QByteArray fs_source = fs_file.readAll ();

        if (QOpenGLContext::currentContext ()->isOpenGLES ()) {
            vs_source.prepend (QByteArrayLiteral ("#version 300 es\n"));
            fs_source.prepend (QByteArrayLiteral ("#version 300 es\n"));
        } else {
            vs_source.prepend (QByteArrayLiteral ("#version 410\n"));
            fs_source.prepend (QByteArrayLiteral ("#version 410\n"));
        }

        _program_background.addShaderFromSourceCode (QOpenGLShader::Vertex, vs_source);
        _program_background.addShaderFromSourceCode (QOpenGLShader::Fragment, fs_source);
        _program_background.link ();
    }
    // object shaders
    {
        QFile vs_file (":/GL_shaders/object_vs.glsl");
        QFile fs_file (":/GL_shaders/object_fs.glsl");
        vs_file.open (QIODevice::ReadOnly);
        fs_file.open (QIODevice::ReadOnly);
        QByteArray vs_source = vs_file.readAll ();
        QByteArray fs_source = fs_file.readAll ();

        if (QOpenGLContext::currentContext ()->isOpenGLES ()) {
            vs_source.prepend (QByteArrayLiteral ("#version 300 es\n"));
            fs_source.prepend (QByteArrayLiteral ("#version 300 es\n"));
        } else {
            vs_source.prepend (QByteArrayLiteral ("#version 410\n"));
            fs_source.prepend (QByteArrayLiteral ("#version 410\n"));
        }

        _program_object.addShaderFromSourceCode (QOpenGLShader::Vertex, vs_source);
        _program_object.addShaderFromSourceCode (QOpenGLShader::Fragment, fs_source);
        _program_object.link ();
    }
    _opengl_mutex.unlock ();
}

void augmentation_widget::resizeGL (int width, int height) {
    _opengl_mutex.lock ();
    _view_width  = width;
    _view_height = height;
    glViewport (0, 0, width, height);

    _mat_projection.setToIdentity ();
    // TODO: replace with perspective, or possibly intrinsic camera matrix
    _mat_projection.ortho (-2.0f, +2.0f, -2.0f, +2.0f, 1.0f, 25.0f);
    _opengl_mutex.unlock ();
}

void augmentation_widget::paintGL () {
    _opengl_mutex.lock ();
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // draw background
    _program_background.bind ();
    draw_background ();

    // draw object
    QMatrix4x4 mat_modelview;
    mat_modelview.translate (_x_pos, _y_pos, -10.0);
    mat_modelview.scale (_scale_factor);
    mat_modelview.rotate (_x_rot, 1, 0, 0);
    mat_modelview.rotate (_y_rot, 0, 1, 0);
    mat_modelview.rotate (_z_rot, 0, 0, 1);
    mat_modelview = _mat_projection * mat_modelview;

    _program_object.bind ();
    _program_object.setUniformValue ("view_matrix", mat_modelview);
    draw_object ();
    _opengl_mutex.unlock ();
}

void augmentation_widget::draw_object () {
    _opengl_mutex.lock ();
    // draw the object
    glBindVertexArray (_object_vao);
    glDrawArrays (GL_TRIANGLES, 0, _vertex_count);
    glBindVertexArray (0);
    _opengl_mutex.unlock ();
}

void augmentation_widget::draw_background () {
    _opengl_mutex.lock ();
    // draw the 2 triangles that form the background
    glBindVertexArray (_background_vao);
    glBindTexture (GL_TEXTURE_2D, _texture_background);
    glDrawArrays (GL_TRIANGLES, 0, 6);
    glBindTexture (GL_TEXTURE_2D, 0);
    glBindVertexArray (0);
    _opengl_mutex.unlock ();
}
<commit_msg>fix debug texture rendering on desktop GL<commit_after>// augmentation_widget.cpp

#include "augmentation_widget.hpp"

#include <QOpenGLExtraFunctions>
#include <QTemporaryFile>
#include <QVector2D>
#include <QVector3D>
#include <math.h>

augmentation_widget::augmentation_widget (QWidget* parent)
: QOpenGLWidget (parent)
, _scale_factor (1.0f)
, _x_pos (0.0f)
, _y_pos (0.0f)
, _opengl_mutex (QMutex::Recursive)
, _last_handle (0)
, _vertex_count (0) {
}

augmentation_widget::~augmentation_widget () {
    _opengl_mutex.lock ();
    glDeleteBuffers (1, &_object_vbo);
    glDeleteVertexArrays (1, &_object_vao);
    _opengl_mutex.unlock ();
}

QSize augmentation_widget::minimumSizeHint () const {
    return QSize (600, 350);
}

QSize augmentation_widget::sizeHint () const {
    return QSize (600, 350);
}

bool augmentation_widget::loadObject (const QString& resource_path) {
    _opengl_mutex.lock ();
    bool status = false;

    // extract model from resources into filesystem and parse it
    QFile resource_file (resource_path);
    if (resource_file.exists ()) {
        auto temp_file  = QTemporaryFile::createNativeFile (resource_file);
        QString fs_path = temp_file->fileName ();

        if (!fs_path.isEmpty ()) {
            std::vector<float> model_interleaved = _object.load (fs_path.toStdString ());

            glBindBuffer (GL_ARRAY_BUFFER, _object_vbo);
            glBufferData (GL_ARRAY_BUFFER, sizeof (float) * model_interleaved.size (),
            model_interleaved.data (), GL_STATIC_DRAW);
            glBindBuffer (GL_ARRAY_BUFFER, 0);
            _vertex_count = model_interleaved.size () / _object.data_per_vertex ();
            _object.release ();

            status = true;
        }
    }
    _opengl_mutex.unlock ();
    return status;
}

void augmentation_widget::downloadImage (image_t& image, GLuint handle) {
    _opengl_mutex.lock ();

    QOpenGLContext* ctx = QOpenGLContext::currentContext ();
    QOpenGLFunctions* f = ctx->functions ();
    GLuint fbo;
    f->glGenFramebuffers (1, &fbo);
    GLuint prevFbo;
    f->glGetIntegerv (GL_FRAMEBUFFER_BINDING, (GLint*)&prevFbo);
    f->glBindFramebuffer (GL_FRAMEBUFFER, fbo);
    f->glFramebufferTexture2D (
    GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, handle, 0);
    f->glReadPixels (
    0, 0, image.width, image.height, GL_RGBA, GL_UNSIGNED_BYTE, image.data);
    f->glBindFramebuffer (GL_FRAMEBUFFER, prevFbo);

    _opengl_mutex.unlock ();
}

void augmentation_widget::setBackground (GLuint tex) {
    // TODO: this might not be the "nicest" way to do this, since it simply
    // ignores the previously generated texture. That texture will be lost,
    // although this only happens once per runtime, so its not THAT bad.
    _opengl_mutex.lock ();
    _texture_background = tex;
    _opengl_mutex.unlock ();
}

void augmentation_widget::setBackground (image_t image) {
    bool status = true;
    GLint format_gl;

    _opengl_mutex.lock ();
    // create background texture
    glBindTexture (GL_TEXTURE_2D, _texture_background);

    switch (image.format) {
        case RGB24: {
            format_gl = GL_RGB;
            break;
        }
        case YUV:
        case GREY8:
        case BINARY8: {
            if (QOpenGLContext::currentContext ()->isOpenGLES ()) {
                format_gl = GL_LUMINANCE;
            } else {
                format_gl = GL_RED;
            }
            break;
        }
        case BGR32: {
            status = false;
            break;
        }
    }

    if (status) {
        glTexImage2D (GL_TEXTURE_2D, 0, format_gl, image.width, image.height, 0,
        format_gl, GL_UNSIGNED_BYTE, image.data);
    }
    glBindTexture (GL_TEXTURE_2D, 0);
    _opengl_mutex.unlock ();
}

void augmentation_widget::setScale (const float scale) {
    _opengl_mutex.lock ();
    _scale_factor = scale;
    _opengl_mutex.unlock ();
}

void augmentation_widget::setXPosition (const float location) {
    _opengl_mutex.lock ();
    _x_pos = location;
    _opengl_mutex.unlock ();
}

void augmentation_widget::setYPosition (const float location) {
    _opengl_mutex.lock ();
    _y_pos = location;
    _opengl_mutex.unlock ();
}

void augmentation_widget::setXRotation (const GLfloat angle) {
    _opengl_mutex.lock ();
    _x_rot = -angle;
    _opengl_mutex.unlock ();
}

void augmentation_widget::setYRotation (const GLfloat angle) {
    _opengl_mutex.lock ();
    _y_rot = -angle;
    _opengl_mutex.unlock ();
}

void augmentation_widget::setZRotation (const GLfloat angle) {
    _opengl_mutex.lock ();
    _z_rot = -angle;
    _opengl_mutex.unlock ();
}

void augmentation_widget::initializeGL () {
    _opengl_mutex.lock ();
    initializeOpenGLFunctions ();

    glClearColor (1, 0.5, 1, 1.0f);
    glEnable (GL_DEPTH_TEST);
    // glEnable (GL_CULL_FACE);
    glEnable (GL_TEXTURE_2D);

    glGenTextures (1, &_texture_background);
    glBindTexture (GL_TEXTURE_2D, _texture_background);
    glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glBindTexture (GL_TEXTURE_2D, 0);

    // generate a buffer to bind to textures
    glGenFramebuffers (1, &_readback_buffer);

    // compile and link shaders
    compile_shaders ();

    // generate vertex array buffers
    generate_buffers ();

    // setup projection matrix
    _mat_projection.ortho (-2.0f, +2.0f, -2.0f, +2.0f, 1.0f, 25.0f);

    emit initialized ();
    _opengl_mutex.unlock ();
}

void augmentation_widget::generate_buffers () {
    _opengl_mutex.lock ();
    // setup background vao
    {
        glGenVertexArrays (1, &_background_vao);
        glGenBuffers (1, &_background_vbo);

        glBindVertexArray (_background_vao);
        glBindBuffer (GL_ARRAY_BUFFER, _background_vbo);

        int pos_location = _program_background.attributeLocation ("position");
        glVertexAttribPointer (pos_location, 2, GL_FLOAT, GL_FALSE,
        4 * sizeof (float), reinterpret_cast<void*> (0));
        glEnableVertexAttribArray (pos_location);

        int tex_location = _program_background.attributeLocation ("tex");
        glVertexAttribPointer (tex_location, 2, GL_FLOAT, GL_FALSE,
        4 * sizeof (float), reinterpret_cast<void*> (2 * sizeof (float)));
        glEnableVertexAttribArray (tex_location);

        // fill buffer with data
        GLfloat interleaved_background_buff[6 * 4] = {
            -1.0, 1.0,  // poly 1 a
            0.0, 0.0,   // poly 1 a tex
            -1.0, -1.0, // poly 1 b
            0.0, 1.0,   // poly 1 b tex
            1.0, 1.0,   // poly 1 c
            1.0, 0.0,   // poly 1 c tex
            1.0, 1.0,   // poly 2 a
            1.0, 0.0,   // poly 2 a tex
            -1.0, -1.0, // poly 2 b
            0.0, 1.0,   // poly 2 b tex
            1.0, -1.0,  // poly 2 c
            1.0, 1.0    // poly 2 c tex
        };
        glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 6 * 4,
        interleaved_background_buff, GL_STATIC_DRAW);

        // bind texture
        int tex_uniform =
        _program_background.uniformLocation ("u_tex_background");
        glActiveTexture (GL_TEXTURE0);
        glBindTexture (GL_TEXTURE_2D, _texture_background);
        glUniform1i (tex_uniform, 0);
        glBindTexture (GL_TEXTURE_2D, 0);
    }

    // setup object vao
    {
        glGenVertexArrays (1, &_object_vao);
        glGenBuffers (1, &_object_vbo);

        glBindVertexArray (_object_vao);
        glBindBuffer (GL_ARRAY_BUFFER, _object_vbo);

        int pos_location = _program_object.attributeLocation ("position");
        glVertexAttribPointer (pos_location, 3, GL_FLOAT, GL_FALSE,
        10 * sizeof (float), reinterpret_cast<void*> (0));
        glEnableVertexAttribArray (pos_location);

        int nor_location = _program_object.attributeLocation ("normal");
        glVertexAttribPointer (nor_location, 3, GL_FLOAT, GL_FALSE,
        10 * sizeof (float), reinterpret_cast<void*> (3 * sizeof (float)));
        glEnableVertexAttribArray (nor_location);

        int col_location = _program_object.attributeLocation ("color");
        glVertexAttribPointer (col_location, 4, GL_FLOAT, GL_FALSE,
        10 * sizeof (float), reinterpret_cast<void*> (6 * sizeof (float)));
        glEnableVertexAttribArray (col_location);

        glBindBuffer (GL_ARRAY_BUFFER, 0);
        glBindVertexArray (0);
    }
    _opengl_mutex.unlock ();
}

void augmentation_widget::compile_shaders () {
    _opengl_mutex.lock ();
    // background shaders
    {
        QFile vs_file (":/GL_shaders/background_vs.glsl");
        QFile fs_file (":/GL_shaders/background_fs.glsl");
        vs_file.open (QIODevice::ReadOnly);
        fs_file.open (QIODevice::ReadOnly);
        QByteArray vs_source = vs_file.readAll ();
        QByteArray fs_source = fs_file.readAll ();

        if (QOpenGLContext::currentContext ()->isOpenGLES ()) {
            vs_source.prepend (QByteArrayLiteral ("#version 300 es\n"));
            fs_source.prepend (QByteArrayLiteral ("#version 300 es\n"));
        } else {
            vs_source.prepend (QByteArrayLiteral ("#version 410\n"));
            fs_source.prepend (QByteArrayLiteral ("#version 410\n"));
        }

        _program_background.addShaderFromSourceCode (QOpenGLShader::Vertex, vs_source);
        _program_background.addShaderFromSourceCode (QOpenGLShader::Fragment, fs_source);
        _program_background.link ();
    }
    // object shaders
    {
        QFile vs_file (":/GL_shaders/object_vs.glsl");
        QFile fs_file (":/GL_shaders/object_fs.glsl");
        vs_file.open (QIODevice::ReadOnly);
        fs_file.open (QIODevice::ReadOnly);
        QByteArray vs_source = vs_file.readAll ();
        QByteArray fs_source = fs_file.readAll ();

        if (QOpenGLContext::currentContext ()->isOpenGLES ()) {
            vs_source.prepend (QByteArrayLiteral ("#version 300 es\n"));
            fs_source.prepend (QByteArrayLiteral ("#version 300 es\n"));
        } else {
            vs_source.prepend (QByteArrayLiteral ("#version 410\n"));
            fs_source.prepend (QByteArrayLiteral ("#version 410\n"));
        }

        _program_object.addShaderFromSourceCode (QOpenGLShader::Vertex, vs_source);
        _program_object.addShaderFromSourceCode (QOpenGLShader::Fragment, fs_source);
        _program_object.link ();
    }
    _opengl_mutex.unlock ();
}

void augmentation_widget::resizeGL (int width, int height) {
    _opengl_mutex.lock ();
    _view_width  = width;
    _view_height = height;
    glViewport (0, 0, width, height);

    _mat_projection.setToIdentity ();
    // TODO: replace with perspective, or possibly intrinsic camera matrix
    _mat_projection.ortho (-2.0f, +2.0f, -2.0f, +2.0f, 1.0f, 25.0f);
    _opengl_mutex.unlock ();
}

void augmentation_widget::paintGL () {
    _opengl_mutex.lock ();
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // draw background
    _program_background.bind ();
    draw_background ();

    // draw object
    QMatrix4x4 mat_modelview;
    mat_modelview.translate (_x_pos, _y_pos, -10.0);
    mat_modelview.scale (_scale_factor);
    mat_modelview.rotate (_x_rot, 1, 0, 0);
    mat_modelview.rotate (_y_rot, 0, 1, 0);
    mat_modelview.rotate (_z_rot, 0, 0, 1);
    mat_modelview = _mat_projection * mat_modelview;

    _program_object.bind ();
    _program_object.setUniformValue ("view_matrix", mat_modelview);
    draw_object ();
    _opengl_mutex.unlock ();
}

void augmentation_widget::draw_object () {
    _opengl_mutex.lock ();
    // draw the object
    glBindVertexArray (_object_vao);
    glDrawArrays (GL_TRIANGLES, 0, _vertex_count);
    glBindVertexArray (0);
    _opengl_mutex.unlock ();
}

void augmentation_widget::draw_background () {
    _opengl_mutex.lock ();
    // draw the 2 triangles that form the background
    glBindVertexArray (_background_vao);
    glBindTexture (GL_TEXTURE_2D, _texture_background);
    glDrawArrays (GL_TRIANGLES, 0, 6);
    glBindTexture (GL_TEXTURE_2D, 0);
    glBindVertexArray (0);
    _opengl_mutex.unlock ();
}
<|endoftext|>


<commit_before>#include "etl_image.hpp"

namespace nervana {

    /* Extract */
    image_extractor::image_extractor(param_ptr_t image_extractor_params)
    {
        _channel_count = image_extractor_params->get_channel_count();
        if !(_channel_count == 1 || _channel_count == 3)
        {
            std::stringstream ss;
            ss << "Unsupported number of channels in image: " << _channel_count;
            throw std::runtime_error(ss.str());
        } else {
            _pixel_type = _channel_count == 1 ? CV_8UC1 : CV_8UC3;
            _color_mode = _channel_count == 1 ? CV_LOAD_IMAGE_GRAYSCALE : CV_LOAD_IMAGE_COLOR;
        }

    }

    media_ptr_t image_extractor::extract(char* inbuf, int insize)
    {
        auto output = make_shared<decoded_image>();
        cv::Mat input_img(1, insize, _pixel_type, inbuf);
        cv::imdecode(input_img, _color_mode, output->get_image());
        return static_pointer_cast<decoded_media>(output);
    }

    image_transformer::image_transformer(param_ptr_t image_transformer_params)
    {

    }

    media_ptr_t image_transformer::transform(settings_ptr_t transform_settings,
                                             const media_ptr_t& input)
    {
        fill_settings(transform_settings)

        cv::Mat rotatedImage;
        auto img = static_pointer_cast<decoded_image>(input);
        rotate(img->get_image(), rotatedImage, transform_settings->get_angle());
        cv::Mat croppedImage = rotatedImage(transform_settings->get_cropbox());

        cv::Mat resizedImage;
        resize(croppedImage, resizedImage, transform_settings->get_size());
        cbsjitter(croppedImage, transform_settings->get_cbs());
        lighting(croppedImage, transform_settings->get_colornoise());

        cv::Mat *finalImage = &resizedImage;
        cv::Mat flippedImage;
        if (transform_settings->get_flip()) {
            cv::flip(resizedImage, flippedImage, 1);
            finalImage = &flippedImage;
        }

        auto output = make_shared<decoded_image>(*finalImage);
        return static_pointer_cast<decoded_media>(output);
    }

    void image_transformer::fill_settings(settings_ptr_t settings)
    {
        if (settings->filled())
        {
            return;
        }

    }

    void image_transformer::rotate(const cv::Mat& input, cv::Mat& output, int angle)
    {
        if (angle == 0) {
            output = input;
        } else {
            cv::Point2i pt(input.cols / 2, input.rows / 2);
            cv::Mat rot = cv::getRotationMatrix2D(pt, angle, 1.0);
            cv::warpAffine(input, output, rot, input.size());
        }
    }

    void image_transformer::resize(const cv::Mat& input, cv::Mat& output, const cv::Size2i& size)
    {
        if (size == input.size()) {
            output = input;
        } else {
            int inter = input.size().area() < size.area() ? CV_INTER_CUBIC : CV_INTER_AREA;
            cv::resize(input, output, size, 0, 0, inter);
        }
    }

    void image_transformer::lighting(cv::Mat& inout, float pixelstd[])
    {
    }

    void image_transformer::cbsjitter(cv::Mat& inout, float cbs[])
    {
    }

    image_loader::image_loader(param_ptr_t image_loader_params) {}

    void image_loader::load(char* outbuf, int outsize, const media_ptr_t& input)
    {
        auto img = static_pointer_cast<decoded_image>(input);
        this->split(img->get_image(), outbuf, outsize);
    }

    void image_loader::split(cv::Mat& img, char* buf, int bufSize)
    {
        int pix_per_channel = img.total();
        int num_channels = img.channels();
        int all_pixels = pix_per_channel * num_channels;

        if (all_pixels > bufSize) {
            throw std::runtime_error("Decode failed - buffer too small");
        }

        if (num_channels == 1) {
            memcpy(buf, img.data, all_pixels);
            return;
        }

        // Split into separate channels
        cv::Size2i size = img.size();
        cv::Mat b(size, CV_8U, buf);
        cv::Mat g(size, CV_8U, buf + pix_per_channel);
        cv::Mat r(size, CV_8U, buf + 2 * pix_per_channel);

        cv::Mat channels[3] = {b, g, r};
        cv::split(img, channels);
    }

}
<commit_msg>Commenting on what needs to be done for transform settings<commit_after>#include "etl_image.hpp"

namespace nervana {

    /* Extract */
    image_extractor::image_extractor(param_ptr_t image_extractor_params)
    {
        _channel_count = image_extractor_params->get_channel_count();
        if !(_channel_count == 1 || _channel_count == 3)
        {
            std::stringstream ss;
            ss << "Unsupported number of channels in image: " << _channel_count;
            throw std::runtime_error(ss.str());
        } else {
            _pixel_type = _channel_count == 1 ? CV_8UC1 : CV_8UC3;
            _color_mode = _channel_count == 1 ? CV_LOAD_IMAGE_GRAYSCALE : CV_LOAD_IMAGE_COLOR;
        }

    }

    media_ptr_t image_extractor::extract(char* inbuf, int insize)
    {
        cv::Mat output_img;
        cv::Mat input_img(1, insize, _pixel_type, inbuf);
        cv::imdecode(input_img, _color_mode, output_img);

        auto output = make_shared<decoded_image>(output_img);
        return static_pointer_cast<decoded_media>(output);
    }

    /* Transform:
        transformer_params will be a supplied bunch of settings used by this provider.
        on each record, the transformer will use the transform_params along with the supplied
        record to fill a transform_settings structure which will have

        Spatial distortion settings:
        randomly sampled crop box (based on params->center, params->aspect_ratio, params->scale_pct, record size)
        randomly determined flip (based on params->flip)
        randomly sampled rotation angle (based on params->angle)

        Photometric distortion settings:
        randomly sampled contrast, brightness, saturation, lighting values (based on params->cbs, lighting bounds)

    */
    image_transformer::image_transformer(param_ptr_t image_transformer_params)
    {
        // should we be doing anything in here?
    }

    media_ptr_t image_transformer::transform(settings_ptr_t transform_settings,
                                             const media_ptr_t& input)
    {
        fill_settings(transform_settings)

        cv::Mat rotatedImage;
        auto img = static_pointer_cast<decoded_image>(input);
        rotate(img->get_image(), rotatedImage, transform_settings->get_angle());
        cv::Mat croppedImage = rotatedImage(transform_settings->get_cropbox());

        cv::Mat resizedImage;
        resize(croppedImage, resizedImage, transform_settings->get_size());
        cbsjitter(croppedImage, transform_settings->get_cbs());
        lighting(croppedImage, transform_settings->get_colornoise());

        cv::Mat *finalImage = &resizedImage;
        cv::Mat flippedImage;
        if (transform_settings->get_flip()) {
            cv::flip(resizedImage, flippedImage, 1);
            finalImage = &flippedImage;
        }

        auto output = make_shared<decoded_image>(*finalImage);
        return static_pointer_cast<decoded_media>(output);
    }

    void image_transformer::fill_settings(settings_ptr_t settings)
    {
        if (settings->filled())
        {
            return;
        }

    }

    void image_transformer::rotate(const cv::Mat& input, cv::Mat& output, int angle)
    {
        if (angle == 0) {
            output = input;
        } else {
            cv::Point2i pt(input.cols / 2, input.rows / 2);
            cv::Mat rot = cv::getRotationMatrix2D(pt, angle, 1.0);
            cv::warpAffine(input, output, rot, input.size());
        }
    }

    void image_transformer::resize(const cv::Mat& input, cv::Mat& output, const cv::Size2i& size)
    {
        if (size == input.size()) {
            output = input;
        } else {
            int inter = input.size().area() < size.area() ? CV_INTER_CUBIC : CV_INTER_AREA;
            cv::resize(input, output, size, 0, 0, inter);
        }
    }

    void image_transformer::lighting(cv::Mat& inout, float pixelstd[])
    {
    }

    void image_transformer::cbsjitter(cv::Mat& inout, float cbs[])
    {
    }

    image_loader::image_loader(param_ptr_t image_loader_params) {}

    void image_loader::load(char* outbuf, int outsize, const media_ptr_t& input)
    {
        auto img = static_pointer_cast<decoded_image>(input);
        this->split(img->get_image(), outbuf, outsize);
    }

    void image_loader::split(cv::Mat& img, char* buf, int bufSize)
    {
        int pix_per_channel = img.total();
        int num_channels = img.channels();
        int all_pixels = pix_per_channel * num_channels;

        if (all_pixels > bufSize) {
            throw std::runtime_error("Decode failed - buffer too small");
        }

        if (num_channels == 1) {
            memcpy(buf, img.data, all_pixels);
            return;
        }

        // Split into separate channels
        cv::Size2i size = img.size();
        cv::Mat b(size, CV_8U, buf);
        cv::Mat g(size, CV_8U, buf + pix_per_channel);
        cv::Mat r(size, CV_8U, buf + 2 * pix_per_channel);

        cv::Mat channels[3] = {b, g, r};
        cv::split(img, channels);
    }

}
<|endoftext|>


<commit_before>//
// Copyright (c) 2015-2016 CNRS
//
// This file is part of Pinocchio
// Pinocchio is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation, either version
// 3 of the License, or (at your option) any later version.
//
// Pinocchio is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Lesser Public License for more details. You should have
// received a copy of the GNU Lesser General Public License along with
// Pinocchio If not, see
// <http://www.gnu.org/licenses/>.

#ifndef __se3_jacobian_hpp__
#define __se3_jacobian_hpp__

#include "pinocchio/multibody/model.hpp"

namespace se3
{
  ///
  /// \brief Computes the full model Jacobian, i.e. the stack of all motion subspace expressed in the world frame.
  ///        The result is accessible throw data.J.
  ///
  /// \note This Jacobian does not correspond to any specific joint frame Jacobian. From this Hacobian, it is then possible to easily extract the Jacobian of a specific joint frame.
  ///
  /// \param[in] model The model structure of the rigid body system.
  /// \param[in] data The data structure of the rigid body system.
  /// \param[in] q The joint configuration vector (dim model.nq).
  ///
  /// \return The full model Jacobian (matrix 6 x model.nv).
  ///
  inline const Data::Matrix6x &
  computeJacobians(const Model & model,
                   Data & data,
                   const Eigen::VectorXd & q);

  ///
  /// \brief Computes the Jacobian of a specific joint frame expressed either in the world frame or in the local frame of the joint.
  /// \note This jacobian is extracted from data.J. You have to run se3::computeJacobians before calling it.
  ///
  /// \param[in] localFrame Expressed the Jacobian in the local frame or world frame coordinates system.
  /// \param[in] model The model structure of the rigid body system.
  /// \param[in] data The data structure of the rigid body system.
  /// \param[in] jointId The id of the joint.
  /// \param[out] J A reference on the Jacobian matrix where the results will be stored in (dim 6 x model.nv).
  ///
  template<bool localFrame>
  void getJacobian(const Model & model,
                   const Data & data,
                   const Model::JointIndex jointId,
                   Data::Matrix6x & J);

  ///
  /// \brief Computes the Jacobian of a specific joint frame expressed in the local frame of the joint. The result is stored in data.J.
  ///
  /// \param[in] model The model structure of the rigid body system.
  /// \param[in] data The data structure of the rigid body system.
  /// \param[in] q The joint configuration vector (dim model.nq).
  /// \param[in] jointId The id of the joint.
  ///
  /// \return The Jacobian of the specific joint frame expressed in the local frame of the joint (matrix 6 x model.nv).
  ///
  inline const Data::Matrix6x &
  jacobian(const Model & model,
           Data & data,
           const Eigen::VectorXd & q,
           const Model::JointIndex jointId);

} // namespace se3

/* --- Details -------------------------------------------------------------------- */
/* --- Details -------------------------------------------------------------------- */
/* --- Details -------------------------------------------------------------------- */

#include "pinocchio/algorithm/jacobian.hxx"

#endif // ifndef __se3_jacobian_hpp__
<commit_msg>[Doc] Correct documentation in getJacobian<commit_after>//
// Copyright (c) 2015-2016 CNRS
//
// This file is part of Pinocchio
// Pinocchio is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation, either version
// 3 of the License, or (at your option) any later version.
//
// Pinocchio is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Lesser Public License for more details. You should have
// received a copy of the GNU Lesser General Public License along with
// Pinocchio If not, see
// <http://www.gnu.org/licenses/>.

#ifndef __se3_jacobian_hpp__
#define __se3_jacobian_hpp__

#include "pinocchio/multibody/model.hpp"

namespace se3
{
  ///
  /// \brief Computes the full model Jacobian, i.e. the stack of all motion subspace expressed in the world frame.
  ///        The result is accessible throw data.J.
  ///
  /// \note This Jacobian does not correspond to any specific joint frame Jacobian. From this Hacobian, it is then possible to easily extract the Jacobian of a specific joint frame.
  ///
  /// \param[in] model The model structure of the rigid body system.
  /// \param[in] data The data structure of the rigid body system.
  /// \param[in] q The joint configuration vector (dim model.nq).
  ///
  /// \return The full model Jacobian (matrix 6 x model.nv).
  ///
  inline const Data::Matrix6x &
  computeJacobians(const Model & model,
                   Data & data,
                   const Eigen::VectorXd & q);

  ///
  /// \brief Computes the Jacobian of a specific joint frame expressed either in the world frame or in the local frame of the joint.
  /// \note This jacobian is extracted from data.J. You have to run se3::computeJacobians before calling it.
  ///
  /// \param[in] localFrame Expressed the Jacobian in the local frame or world frame coordinates system.
  /// \param[in] model The model structure of the rigid body system.
  /// \param[in] data The data structure of the rigid body system.
  /// \param[in] jointId The id of the joint.
  /// \param[out] J A reference on the Jacobian matrix where the results will be stored in (dim 6 x model.nv). You must fill J with zero elements, e.g. J.fill(0.).
  ///
  template<bool localFrame>
  void getJacobian(const Model & model,
                   const Data & data,
                   const Model::JointIndex jointId,
                   Data::Matrix6x & J);

  ///
  /// \brief Computes the Jacobian of a specific joint frame expressed in the local frame of the joint. The result is stored in data.J.
  ///
  /// \param[in] model The model structure of the rigid body system.
  /// \param[in] data The data structure of the rigid body system.
  /// \param[in] q The joint configuration vector (dim model.nq).
  /// \param[in] jointId The id of the joint.
  ///
  /// \return The Jacobian of the specific joint frame expressed in the local frame of the joint (matrix 6 x model.nv).
  ///
  inline const Data::Matrix6x &
  jacobian(const Model & model,
           Data & data,
           const Eigen::VectorXd & q,
           const Model::JointIndex jointId);

} // namespace se3

/* --- Details -------------------------------------------------------------------- */
/* --- Details -------------------------------------------------------------------- */
/* --- Details -------------------------------------------------------------------- */

#include "pinocchio/algorithm/jacobian.hxx"

#endif // ifndef __se3_jacobian_hpp__
<|endoftext|>