<commit_before>/**************************************************************************************/
/*                                                                                */
/*  Visualization Library                                                             */
/*  http://www.visualizationlibrary.com                                               */
/*                                                                                */
/*  Copyright (c) 2005-2010, Michele Bosi                                             */
/*  All rights reserved.                                                              */
/*                                                                                */
/*  Redistribution and use in source and binary forms, with or without modification,  */
/*  are permitted provided that the following conditions are met:                     */
/*                                                                                */
/*  - Redistributions of source code must retain the above copyright notice, this     */
/*  list of conditions and the following disclaimer.                                  */
/*                                                                                */
/*  - Redistributions in binary form must reproduce the above copyright notice, this  */
/*  list of conditions and the following disclaimer in the documentation and/or       */
/*  other materials provided with the distribution.                                   */
/*                                                                                */
/*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
/*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
/*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
/*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
/*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
/*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
/*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
/*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
/*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
/*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
/*                                                                                */
/**************************************************************************************/

///////////////////////////////////////////////////////////////////////////////
// Visualization Library Configuration File
///////////////////////////////////////////////////////////////////////////////

/**
 * \file config.hpp
 * Visualization Library configuration file.
*/

#ifndef VISUALIZATION_LIBRARY_CONFIG_INCLUDE_ONCE
#define VISUALIZATION_LIBRARY_CONFIG_INCLUDE_ONCE

/**
 * Show a message box upon check failure. Only for Win32 platforms.
 * 1 = opens a MessageBox on failed check\n
 * 0 = opens a MessageBox on failed check\n
 */
#define VL_MESSAGEBOX_CHECK 0

/**
 * Defines the maximum number of LOD levels available to the Actor class.
 */
#define VL_MAX_ACTOR_LOD 4

/**
 * Defines the maximum number of LOD levels available to the Effect class.
 */
#define VL_MAX_EFFECT_LOD 4

/**
 * Forces checks to be done also in non debug modes.
 *
 * if set to 1 the VL_CHECK() and VL_CHECK_OGL() macros will be active also in release mode builds
 * if set to 0 the VL_CHECK() and VL_CHECK_OGL() macros will be active only in debug mode builds
 */
#define VL_FORCE_CHECKS 0

/**
 * This define is used to set Visualization Library's pipeline precision.
 *
 * - 1 = use floating point single precision pipeline
 * - 2 = use floating point double precision pipeline
 *
 * In single precision mode the classes \p vec4, \p vec3, \p vec2, \p mat4, \p mat3, \p mat2 will be defined as typedefs to their \p fvec4, \p fmat4 etc. counter parts.
 *
 * In double precision mode the classes \p vec4, \p vec3, \p vec2, \p mat4, \p mat3, \p mat2 will be defined as typedefs to their \p dvec4, \p dmat4 etc. counter parts.
 *
 * In single precision mode vl::Real is defined as \p float, in double precision mode vl::Real is defined as \p double.
 *
 * Other classes are affected as well, in particular vl::Transform, vl::quat, vl::AABB and vl::Sphere.
 */
#define VL_PIPELINE_PRECISION 1

/**
 * Set this to 1 to be able to attach user data to any vl::Object using the
 * setUserData(void*) and void* userData() methods.
 * Useful to glue VL classes to the user's application logic.
 * \note This will add 4 or 8 bytes to each vl::Object instance.
 */
#define VL_OBJECT_USER_DATA 0

/**
 * Set this to 1 to be able to attach user data to any vl::Actor using the
 * setActorUserData(void*) and void* actorUserData() methods.
 * Useful to glue VL classes to the user's application logic.
 * \note This will add 4 or 8 bytes to each vl::Actor instance.
 */
#define VL_ACTOR_USER_DATA 0

/**
 * Set this to 1 to be able to attach user data to any vl::Transform using the
 * "void setTransformUserData(void*)" and "void* transformUserData()" methods.
 * Useful to glue Transform objects to the user's application animation engine.
 * \note This will add 4 or 8 bytes to each vl::Transform instance.
 */
#define VL_TRANSFORM_USER_DATA 0

/**
 * Set this to 1 to be able to attach user data to any vl::Shader using the
 * "void setShaderUserData(void*)" and "void* shaderUserData()" methods.
 * Useful to glue Shader objects and the user's application logic.
 * \note This will add 4 or 8 bytes to each vl::Shader instance.
 */
#define VL_SHADER_USER_DATA 0

/**
 * Enables fast square root computation when using single precision mode.
 *
 * - 0 = disable fast square roots when in single precision floating point pipeline
 * - 1 = enable fast square roots when in single precision floating point pipeline
 *
 * Potential performance improvements:
 * - float sqrt will be up to 1.4x quicker
 * - float 1.0/sqrt will be up to 3x quicker
 * - vec3 normalization will be up to 2x quicker
 *
 * Please note that the precision of such operations is seriously affected.
 * Use with care! Under some platforms / compiler configurations this might produce wrong results,
 * like objects disappearing, transforms, matrices and vectors filled with garbage data etc.
 */
#define VL_FAST_SQUARE_ROOTS 0

/**
 * Maximum number of texture units used.
 *
 * - minimum = 1
 * - maximum = OpenGL implementation dependent
 */
#define VL_MAX_TEXTURE_UNITS 6

/**
 * Maximum number of generic vertex attributes used by a single Geometry.
 *
 * - minimum = 1
 * - maximum = OpenGL implementation dependent
 */
#define VL_MAX_GENERIC_VERTEX_ATTRIB 6

/**
 * Enable String copy-on-write mode.
 *
 * - 1 = vl::String copy on write feature enabled
 * - 0 = vl::String copy on write feature disabled
 */
#define VL_STRING_COPY_ON_WRITE 1

/**
 * Default byte alignment for the vl::Buffer class.
 */
#define VL_DEFAULT_BUFFER_BYTE_ALIGNMENT 16

/**
 * Maximum timer index that can be passed to vl::Time::start(int index), vl::Time::stop(int index) etc.
 */
#define VL_MAX_TIMERS 16

/**
 * Enable/disable memory leaks debugging.
 *
 * - 0 = disable memory leaks debugging
 * - 1 = Objects::mDebug_LivingObjects will contain the set of currently living Object-s.
 *
 * This is useful when you want to track memory leaks and object construction/destruction.
 */
#define VL_DEBUG_LIVING_OBJECTS 0

// -------------------- Do Not Touch The Following Section --------------------

///////////////////////////////////////////////////

#ifndef NDEBUG
  #define VL_DEBUG_SET_OBJECT_NAME() this->mObjectName = className();
#else
  #define VL_DEBUG_SET_OBJECT_NAME()
#endif

///////////////////////////////////////////////////

// Pipeline precision settings
#if VL_PIPELINE_PRECISION == 2
  namespace vl { /** Defined as \p 'typedef \p double \p Real' */ typedef double Real; }
  //! Defined as \p glLoadMatrixd, used internally.
  #define VL_glLoadMatrix glLoadMatrixd
  //! Defined as \p glMultMatrixd, used internally.
  #define VL_glMultMatrix glMultMatrixd
#else
  namespace vl { /** Defined as \p 'typedef \p float \p Real' */ typedef float Real; }
  namespace vl { typedef float Real; }
  //! Defined as \p glLoadMatrixf, used internally.
  #define VL_glLoadMatrix glLoadMatrixf
  //! Defined as \p glMultMatrixf, used internally.
  #define VL_glMultMatrix glMultMatrixf
#endif

///////////////////////////////////////////////////

// Visual Studio special settings
#ifdef _MSC_VER
  #pragma warning( once : 4996 ) // function or variable may be unsafe
  #pragma warning( once : 4800 ) // forcing value to bool (performance warning)
  #pragma warning( once : 4127 ) // conditional expression is constant
  #pragma warning( once : 4100 ) // unreferenced formal parameter
  #pragma warning( disable : 4251 ) // non-dll type exposed by a dll type
#endif

///////////////////////////////////////////////////

// VLCORE_EXPORT macro
#if defined(_WIN32) && !defined(VL_STATIC_LINKING)
  #ifdef VLCore_EXPORTS
    #define VLCORE_EXPORT __declspec(dllexport)
  #else
    #define VLCORE_EXPORT __declspec(dllimport)
  #endif
#else
  #define VLCORE_EXPORT
#endif

#endif // VISUALIZATION_LIBRARY_CONFIG_INCLUDE_ONCE
<commit_msg>Updated config.hpp documentation and set to 8 both VL_MAX_TEXTURE_UNITS and VL_MAX_GENERIC_VERTEX_ATTRIB.<commit_after>/**************************************************************************************/
/*                                                                                */
/*  Visualization Library                                                             */
/*  http://www.visualizationlibrary.com                                               */
/*                                                                                */
/*  Copyright (c) 2005-2010, Michele Bosi                                             */
/*  All rights reserved.                                                              */
/*                                                                                */
/*  Redistribution and use in source and binary forms, with or without modification,  */
/*  are permitted provided that the following conditions are met:                     */
/*                                                                                */
/*  - Redistributions of source code must retain the above copyright notice, this     */
/*  list of conditions and the following disclaimer.                                  */
/*                                                                                */
/*  - Redistributions in binary form must reproduce the above copyright notice, this  */
/*  list of conditions and the following disclaimer in the documentation and/or       */
/*  other materials provided with the distribution.                                   */
/*                                                                                */
/*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
/*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
/*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
/*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
/*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
/*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
/*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
/*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
/*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
/*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
/*                                                                                */
/**************************************************************************************/

///////////////////////////////////////////////////////////////////////////////
// Visualization Library Configuration File
///////////////////////////////////////////////////////////////////////////////

/**
 * \file config.hpp
 * Visualization Library configuration file.
*/

#ifndef VISUALIZATION_LIBRARY_CONFIG_INCLUDE_ONCE
#define VISUALIZATION_LIBRARY_CONFIG_INCLUDE_ONCE

/**
 * Enable/disable memory leaks debugging.
 *
 * - 0 = disable memory leaks debugging
 * - 1 = Objects::mDebug_LivingObjects will contain the set of currently living Object-s.
 *
 * This is useful when you want to track memory leaks and object construction/destruction.
 */
#define VL_DEBUG_LIVING_OBJECTS 0

/**
 * Forces checks to be done also in non debug modes.
 *
 * if set to 1 the VL_CHECK() and VL_CHECK_OGL() macros will be active also in release mode builds
 * if set to 0 the VL_CHECK() and VL_CHECK_OGL() macros will be active only in debug mode builds
 */
#define VL_FORCE_CHECKS 0

/**
 * Show a message box upon check failure. Only for Win32 platforms.
 * 1 = opens a MessageBox on failed check\n
 * 0 = opens a MessageBox on failed check\n
 */
#define VL_MESSAGEBOX_CHECK 0

/**
 * This define is used to set Visualization Library's pipeline precision.
 *
 * - 1 = use floating point single precision pipeline
 * - 2 = use floating point double precision pipeline
 *
 * In single precision mode the classes \p vec4, \p vec3, \p vec2, \p mat4, \p mat3, \p mat2 will be defined as typedefs to their \p fvec4, \p fmat4 etc. counter parts.
 *
 * In double precision mode the classes \p vec4, \p vec3, \p vec2, \p mat4, \p mat3, \p mat2 will be defined as typedefs to their \p dvec4, \p dmat4 etc. counter parts.
 *
 * In single precision mode vl::Real is defined as \p float, in double precision mode vl::Real is defined as \p double.
 *
 * Other classes are affected as well, in particular vl::Transform, vl::quat, vl::AABB and vl::Sphere.
 */
#define VL_PIPELINE_PRECISION 1

/**
 * Enables fast square root computation when using single precision mode.
 *
 * - 0 = disable fast square roots when in single precision floating point pipeline
 * - 1 = enable fast square roots when in single precision floating point pipeline
 *
 * Potential performance improvements:
 * - float sqrt will be up to 1.4x quicker
 * - float 1.0/sqrt will be up to 3x quicker
 * - vec3 normalization will be up to 2x quicker
 *
 * Please note that the precision of such operations is seriously affected.
 * Use with care! Under some platforms / compiler configurations this might produce wrong results,
 * like objects disappearing, transforms, matrices and vectors filled with garbage data etc.
 */
#define VL_FAST_SQUARE_ROOTS 0

/**
 * Set this to 1 to be able to attach user data to any vl::Object using the
 * "setUserData(void*)" and "void* userData()" methods.
 * Useful to glue VL classes to the user's application logic.
 * \note This will add 4 or 8 bytes to each vl::Object instance.
 */
#define VL_OBJECT_USER_DATA 0

/**
 * Set this to 1 to be able to attach user data to any vl::Actor using the
 * "setActorUserData(void*)" and "void* actorUserData()" methods.
 * Useful to glue VL classes to the user's application logic.
 * \note This will add 4 or 8 bytes to each vl::Actor instance.
 */
#define VL_ACTOR_USER_DATA 0

/**
 * Set this to 1 to be able to attach user data to any vl::Transform using the
 * "void setTransformUserData(void*)" and "void* transformUserData()" methods.
 * Useful to glue Transform objects to the user's application animation engine.
 * \note This will add 4 or 8 bytes to each vl::Transform instance.
 */
#define VL_TRANSFORM_USER_DATA 0

/**
 * Set this to 1 to be able to attach user data to any vl::Shader using the
 * "void setShaderUserData(void*)" and "void* shaderUserData()" methods.
 * Useful to glue Shader objects and the user's application logic.
 * \note This will add 4 or 8 bytes to each vl::Shader instance.
 */
#define VL_SHADER_USER_DATA 0

/**
 * Defines the maximum number of LOD levels available to the Actor class.
 * Set this value to optimize VL to your application's needs.
 *
 * - minimum = 1
 * - maximum = application dependent
 */
#define VL_MAX_ACTOR_LOD 4

/**
 * Defines the maximum number of LOD levels available to the Effect class.
 * Set this value to optimize VL to your application's needs.
 *
 * - minimum = 1
 * - maximum = application dependent
 */
#define VL_MAX_EFFECT_LOD 4

/**
 * Maximum number of texture units used.
 * Allows VL to keep track of only the effectively used texture units.
 * Set this value to optimize VL to your application's needs.
 *
 * - minimum = 1
 * - maximum = OpenGL implementation dependent
 */
#define VL_MAX_TEXTURE_UNITS 8

/**
 * Maximum number of generic vertex attributes used by a single Geometry.
 * Allows VL to keep track of only the effectively used vertex attributes.
 * Set this value to optimize VL to your application's needs.
 *
 * - minimum = 1
 * - maximum = OpenGL implementation dependent
 */
#define VL_MAX_GENERIC_VERTEX_ATTRIB 8

/**
 * Maximum timer index that can be passed to vl::Time::start(int index), vl::Time::stop(int index) etc.
 */
#define VL_MAX_TIMERS 16

/**
 * Enable String copy-on-write mode.
 *
 * - 1 = vl::String copy on write feature enabled
 * - 0 = vl::String copy on write feature disabled
 */
#define VL_STRING_COPY_ON_WRITE 1

/**
 * Default byte alignment for the vl::Buffer class.
 */
#define VL_DEFAULT_BUFFER_BYTE_ALIGNMENT 16

// -------------------- Do Not Touch The Following Section --------------------

///////////////////////////////////////////////////

#ifndef NDEBUG
  #define VL_DEBUG_SET_OBJECT_NAME() this->mObjectName = className();
#else
  #define VL_DEBUG_SET_OBJECT_NAME()
#endif

///////////////////////////////////////////////////

// Pipeline precision settings
#if VL_PIPELINE_PRECISION == 2
  namespace vl { /** Defined as \p 'typedef \p double \p Real' */ typedef double Real; }
  //! Defined as \p glLoadMatrixd, used internally.
  #define VL_glLoadMatrix glLoadMatrixd
  //! Defined as \p glMultMatrixd, used internally.
  #define VL_glMultMatrix glMultMatrixd
#else
  namespace vl { /** Defined as \p 'typedef \p float \p Real' */ typedef float Real; }
  namespace vl { typedef float Real; }
  //! Defined as \p glLoadMatrixf, used internally.
  #define VL_glLoadMatrix glLoadMatrixf
  //! Defined as \p glMultMatrixf, used internally.
  #define VL_glMultMatrix glMultMatrixf
#endif

///////////////////////////////////////////////////

// Visual Studio special settings
#ifdef _MSC_VER
  #pragma warning( once : 4996 ) // function or variable may be unsafe
  #pragma warning( once : 4800 ) // forcing value to bool (performance warning)
  #pragma warning( once : 4127 ) // conditional expression is constant
  #pragma warning( once : 4100 ) // unreferenced formal parameter
  #pragma warning( disable : 4251 ) // non-dll type exposed by a dll type
#endif

///////////////////////////////////////////////////

// VLCORE_EXPORT macro
#if defined(_WIN32) && !defined(VL_STATIC_LINKING)
  #ifdef VLCore_EXPORTS
    #define VLCORE_EXPORT __declspec(dllexport)
  #else
    #define VLCORE_EXPORT __declspec(dllimport)
  #endif
#else
  #define VLCORE_EXPORT
#endif

#endif // VISUALIZATION_LIBRARY_CONFIG_INCLUDE_ONCE
<|endoftext|>


<commit_before>#include "Engine.h"
#include "Game.h"
#include "ObjectDummy.h"
#include "BodyRigid.h"
#include "BodyDummy.h"
#include "Physics.h"
#include "ShapeCapsule.h"
#include "ActorBase.h"
#include "Visualizer.h"
#include "sys/SysControl.h"

using namespace MathLib;

#ifdef MEMORY_INFO
#define new new(__FILE__, __LINE__)
#endif // MEMORY_INFO

/*
*/
#define ACTOR_BASE_IFPS             (1.0f / 60.0f)
#define ACTOR_BASE_CLAMP            89.9f
#define ACTOR_BASE_COLLISIONS       4

/*
*/
CActorBase::CActorBase()
{
	m_vUp = vec3(0.0f, 0.0f, 1.0f);
	m_pObject = new CObjectDummy();
	m_pDummy = new CBodyDummy();
	m_pShape = new CShapeCapsule(1.0f, 1.0f);

	m_nFlush = 0;
	m_vPosition = Vec3_zero;
	m_vVelocity = Vec3_zero;
	m_fPhiAngle = 0.0f;			//倾斜角		二维平面坐标系中，直线向Y周延伸的方向与X轴正向之间的夹角
	m_fThetaAngle = 0.0f;			//方位角，正北方那条线与当前线条按照顺时针走过的角度

	for (int i = 0; i < NUM_STATES; i++)
	{
		m_pStates[i] = 0;
		m_pTimes[i] = 0.0f;
	}
	m_pDummy->SetEnabled(1);
	m_pObject->SetBody(NULL);
	m_pObject->SetBody(m_pDummy);
	m_pShape->SetBody(NULL);
	m_pShape->SetBody(m_pDummy);

	m_pObject->SetWorldTransform(Get_Body_Transform());
	m_pShape->SetRestitution(0.0f);
	m_pShape->SetCollisionMask(2);

	SetEnabled(1);
	SetViewDirection(vec3(0.0f, 1.0f, 0.0f));
	SetCollision(1);
	SetCollisionRadius(0.3f);
	SetCollisionHeight(1.0f);
	SetFriction(2.0f);
	SetMinVelocity(2.0f);
	SetMaxVelocity(4.0f);
	SetAcceleration(8.0f);
	SetDamping(8.0f);
	SetJumping(1.5f);

	SetGround(0);
	SetCeiling(0);
}

CActorBase::~CActorBase()
{
	m_pDummy->SetObject(NULL);
	delete m_pObject;
	delete m_pDummy;
}

void CActorBase::SetEnabled(int enable)
{
	m_nEnable = enable;
	m_pDummy->SetEnabled(m_nEnable);
}

int CActorBase::IsEnabled() const
{
	return m_nEnable;
}
void CActorBase::Update(float ifps)
{
	if (!m_nEnable)
	{
		return;
	}

	// impulse
	vec3 impulse = vec3_zero;

	// ortho basis
	vec3 tangent, binormal;
	OrthoBasis(m_vUp, tangent, binormal);

	// current basis
	vec3 x = quat(m_vUp, -m_fPhiAngle) * binormal;
	vec3 y = Normalize(Cross(m_vUp, x));
	vec3 z = Normalize(Cross(x, y));

	handle states
		Update_States(1, ifps);

	// old velocity
	float x_velocity = Dot(x, m_vVelocity);
	float y_velocity = Dot(y, m_vVelocity);
	float z_velocity = Dot(z, m_vVelocity);
	// movement
	if (m_pStates[STATE_FORWARD]) impulse += x;
	if (m_pStates[STATE_BACKWARD]) impulse -= x;
	if (m_pStates[STATE_MOVE_LEFT]) impulse += y;
	if (m_pStates[STATE_MOVE_RIGHT]) impulse -= y;
	impulse.normalize();
	//velocity
	if (m_pStates[STATE_RUN])
		impulse *= m_fMaxVelocity;
	else
		impulse *= m_fMinVelocity;

}<commit_msg>Signed-off-by: mrlitong <litongtongxue@gmail.com><commit_after>#include "Engine.h"
#include "Game.h"
#include "ObjectDummy.h"
#include "BodyRigid.h"
#include "BodyDummy.h"
#include "Physics.h"
#include "ShapeCapsule.h"
#include "ActorBase.h"
#include "Visualizer.h"
#include "sys/SysControl.h"

using namespace MathLib;

#ifdef MEMORY_INFO
#define new new(__FILE__, __LINE__)
#endif // MEMORY_INFO

/*
*/
#define ACTOR_BASE_IFPS             (1.0f / 60.0f)
#define ACTOR_BASE_CLAMP            89.9f
#define ACTOR_BASE_COLLISIONS       4

/*
*/
CActorBase::CActorBase()
{
	m_vUp = vec3(0.0f, 0.0f, 1.0f);
	m_pObject = new CObjectDummy();
	m_pDummy = new CBodyDummy();
	m_pShape = new CShapeCapsule(1.0f, 1.0f);

	m_nFlush = 0;
	m_vPosition = Vec3_zero;
	m_vVelocity = Vec3_zero;
	m_fPhiAngle = 0.0f;			//倾斜角		二维平面坐标系中，直线向Y周延伸的方向与X轴正向之间的夹角
	m_fThetaAngle = 0.0f;			//方位角，正北方那条线与当前线条按照顺时针走过的角度

	for (int i = 0; i < NUM_STATES; i++)
	{
		m_pStates[i] = 0;
		m_pTimes[i] = 0.0f;
	}
	m_pDummy->SetEnabled(1);
	m_pObject->SetBody(NULL);
	m_pObject->SetBody(m_pDummy);
	m_pShape->SetBody(NULL);
	m_pShape->SetBody(m_pDummy);

	m_pObject->SetWorldTransform(Get_Body_Transform());
	m_pShape->SetRestitution(0.0f);
	m_pShape->SetCollisionMask(2);

	SetEnabled(1);
	SetViewDirection(vec3(0.0f, 1.0f, 0.0f));
	SetCollision(1);
	SetCollisionRadius(0.3f);
	SetCollisionHeight(1.0f);
	SetFriction(2.0f);
	SetMinVelocity(2.0f);
	SetMaxVelocity(4.0f);
	SetAcceleration(8.0f);
	SetDamping(8.0f);
	SetJumping(1.5f);

	SetGround(0);
	SetCeiling(0);
}

CActorBase::~CActorBase()
{
	m_pDummy->SetObject(NULL);
	delete m_pObject;
	delete m_pDummy;
}

void CActorBase::SetEnabled(int enable)
{
	m_nEnable = enable;
	m_pDummy->SetEnabled(m_nEnable);
}

int CActorBase::IsEnabled() const
{
	return m_nEnable;
}
void CActorBase::Update(float ifps)
{
	if (!m_nEnable)
	{
		return;
	}

	// impulse
	vec3 impulse = vec3_zero;

	// ortho basis
	vec3 tangent, binormal;
	OrthoBasis(m_vUp, tangent, binormal);

	// current basis
	vec3 x = quat(m_vUp, -m_fPhiAngle) * binormal;
	vec3 y = Normalize(Cross(m_vUp, x));
	vec3 z = Normalize(Cross(x, y));

	handle states
		Update_States(1, ifps);

	// old velocity
	float x_velocity = Dot(x, m_vVelocity);
	float y_velocity = Dot(y, m_vVelocity);
	float z_velocity = Dot(z, m_vVelocity);
	// movement
	if (m_pStates[STATE_FORWARD]) impulse += x;
	if (m_pStates[STATE_BACKWARD]) impulse -= x;
	if (m_pStates[STATE_MOVE_LEFT]) impulse += y;
	if (m_pStates[STATE_MOVE_RIGHT]) impulse -= y;
	impulse.normalize();
	//velocity
	if (m_pStates[STATE_RUN])
		impulse *= m_fMaxVelocity;
	else
		impulse *= m_fMinVelocity;
	// jump
	if (m_pStates[STATE_JUMP] == STATE_BEGIN)
	{
		impulse += z * CMathCore::Sqrt(2.0f * 9.8f * m_fJumping) / (m_fAcceleration * ifps);
	}

}<|endoftext|>


<commit_before>/*
 * Copyright (C) 2017 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include "partition_version.hh"

struct partition_snapshot_reader_dummy_accounter {
   void operator()(const clustering_row& cr) {}
   void operator()(const static_row& sr) {}
   void operator()(const range_tombstone& rt) {}
};
extern partition_snapshot_reader_dummy_accounter no_accounter;

template <typename MemoryAccounter = partition_snapshot_reader_dummy_accounter>
class partition_snapshot_reader : public streamed_mutation::impl, public MemoryAccounter {
    struct rows_position {
        mutation_partition::rows_type::const_iterator _position;
        mutation_partition::rows_type::const_iterator _end;
    };

    class heap_compare {
        rows_entry::compare _cmp;
    public:
        explicit heap_compare(const schema& s) : _cmp(s) { }
        bool operator()(const rows_position& a, const rows_position& b) {
            return _cmp(*b._position, *a._position);
        }
    };
private:
    // Keeps shared pointer to the container we read mutation from to make sure
    // that its lifetime is appropriately extended.
    boost::any _container_guard;

    query::clustering_key_filter_ranges _ck_ranges;
    query::clustering_row_ranges::const_iterator _current_ck_range;
    query::clustering_row_ranges::const_iterator _ck_range_end;
    bool _in_ck_range = false;

    rows_entry::compare _cmp;
    clustering_key_prefix::equality _eq;
    heap_compare _heap_cmp;

    lw_shared_ptr<partition_snapshot> _snapshot;
    stdx::optional<position_in_partition> _last_entry;

    std::vector<rows_position> _clustering_rows;

    range_tombstone_stream _range_tombstones;

    logalloc::region& _lsa_region;
    logalloc::allocating_section& _read_section;

    MemoryAccounter& mem_accounter() {
        return *this;
    }

    uint64_t _reclaim_counter;
    unsigned _version_count = 0;
private:
    void refresh_iterators() {
        _clustering_rows.clear();

        if (!_in_ck_range && _current_ck_range == _ck_range_end) {
            return;
        }

        for (auto&& v : _snapshot->versions()) {
            auto cr_end = v.partition().upper_bound(*_schema, *_current_ck_range);
            auto cr = [&] () -> mutation_partition::rows_type::const_iterator {
                if (_in_ck_range) {
                    return v.partition().clustered_rows().upper_bound(*_last_entry, _cmp);
                } else {
                    return v.partition().lower_bound(*_schema, *_current_ck_range);
                }
            }();

            if (cr != cr_end) {
                _clustering_rows.emplace_back(rows_position { cr, cr_end });
            }
        }

        _in_ck_range = true;
        boost::range::make_heap(_clustering_rows, _heap_cmp);
    }

    // Valid if has_more_rows()
    const rows_entry& pop_clustering_row() {
        boost::range::pop_heap(_clustering_rows, _heap_cmp);
        auto& current = _clustering_rows.back();
        const rows_entry& e = *current._position;
        current._position = std::next(current._position);
        if (current._position == current._end) {
            _clustering_rows.pop_back();
        } else {
            boost::range::push_heap(_clustering_rows, _heap_cmp);
        }
        return e;
    }

    // Valid if has_more_rows()
    const rows_entry& peek_row() const {
        return *_clustering_rows.front()._position;
    }

    bool has_more_rows() const {
        return !_clustering_rows.empty();
    }

    mutation_fragment_opt read_static_row() {
        _last_entry = position_in_partition(position_in_partition::static_row_tag_t());
        mutation_fragment_opt sr;
        for (auto&& v : _snapshot->versions()) {
            if (!v.partition().static_row().empty()) {
                if (!sr) {
                    sr = mutation_fragment(static_row(v.partition().static_row()));
                } else {
                    sr->as_mutable_static_row().apply(*_schema, v.partition().static_row());
                }
            }
        }
        return sr;
    }

    mutation_fragment_opt read_next() {
        if (has_more_rows()) {
            auto mf = _range_tombstones.get_next(peek_row());
            if (mf) {
                return mf;
            }

            clustering_row result = pop_clustering_row();
            while (has_more_rows() && _eq(peek_row().key(), result.key())) {
                result.apply(*_schema, pop_clustering_row());
            }
            _last_entry = position_in_partition(result.position());
            return mutation_fragment(std::move(result));
        }
        return _range_tombstones.get_next();
    }

    void emplace_mutation_fragment(mutation_fragment&& mfopt) {
        mfopt.visit(mem_accounter());
        push_mutation_fragment(std::move(mfopt));
    }

    void do_fill_buffer() {
        if (!_last_entry) {
            auto mfopt = read_static_row();
            if (mfopt) {
                emplace_mutation_fragment(std::move(*mfopt));
            }
        }

        if (!_in_ck_range || _lsa_region.reclaim_counter() != _reclaim_counter || _snapshot->version_count() != _version_count) {
            refresh_iterators();
            _reclaim_counter = _lsa_region.reclaim_counter();
            _version_count = _snapshot->version_count();
        }

        while (!is_end_of_stream() && !is_buffer_full()) {
            if (_in_ck_range && _clustering_rows.empty()) {
                _in_ck_range = false;
                _current_ck_range = std::next(_current_ck_range);
                refresh_iterators();
                continue;
            }

            auto mfopt = read_next();
            if (mfopt) {
                emplace_mutation_fragment(std::move(*mfopt));
            } else {
                _end_of_stream = true;
            }
        }
    }

    static tombstone tomb(partition_snapshot& snp) {
        tombstone t;
        for (auto& v : snp.versions()) {
            t.apply(v.partition().partition_tombstone());
        }
        return t;
    }
public:
    template <typename... Args>
    partition_snapshot_reader(schema_ptr s, dht::decorated_key dk, lw_shared_ptr<partition_snapshot> snp,
        query::clustering_key_filter_ranges crr,
        logalloc::region& region, logalloc::allocating_section& read_section,
        boost::any pointer_to_container, Args&&... args)
    : streamed_mutation::impl(s, std::move(dk), tomb(*snp))
    , MemoryAccounter(std::forward<Args>(args)...)
    , _container_guard(std::move(pointer_to_container))
    , _ck_ranges(std::move(crr))
    , _current_ck_range(_ck_ranges.begin())
    , _ck_range_end(_ck_ranges.end())
    , _cmp(*s)
    , _eq(*s)
    , _heap_cmp(*s)
    , _snapshot(snp)
    , _range_tombstones(*s)
    , _lsa_region(region)
    , _read_section(read_section) {
        for (auto&& v : _snapshot->versions()) {
            auto&& rt_list = v.partition().row_tombstones();
            for (auto&& range : _ck_ranges.ranges()) {
                _range_tombstones.apply(rt_list, range);
            }
        }
        do_fill_buffer();
    }

    ~partition_snapshot_reader() {
        if (!_snapshot.owned()) {
            return;
        }
        // If no one else is using this particular snapshot try to merge partition
        // versions.
        with_allocator(_lsa_region.allocator(), [this] {
            return with_linearized_managed_bytes([this] {
                try {
                    _read_section(_lsa_region, [this] {
                        _snapshot->merge_partition_versions();
                    });
                } catch (...) { }
                _snapshot = {};
            });
        });
    }

    virtual future<> fill_buffer() override {
        return _read_section(_lsa_region, [&] {
            return with_linearized_managed_bytes([&] {
                do_fill_buffer();
                return make_ready_future<>();
            });
        });
    }
};

template <typename MemoryAccounter, typename... Args>
inline streamed_mutation
make_partition_snapshot_reader(schema_ptr s,
    dht::decorated_key dk,
    query::clustering_key_filter_ranges crr,
    lw_shared_ptr<partition_snapshot> snp,
    logalloc::region& region,
    logalloc::allocating_section& read_section,
    boost::any pointer_to_container,
    streamed_mutation::forwarding fwd,
    Args&&... args)
{
    auto sm = make_streamed_mutation<partition_snapshot_reader<MemoryAccounter>>(s, std::move(dk),
           snp, std::move(crr), region, read_section, std::move(pointer_to_container), std::forward<Args>(args)...);
    if (fwd) {
        return make_forwardable(std::move(sm)); // FIXME: optimize
    } else {
        return std::move(sm);
    }
}

inline streamed_mutation
make_partition_snapshot_reader(schema_ptr s,
    dht::decorated_key dk,
    query::clustering_key_filter_ranges crr,
    lw_shared_ptr<partition_snapshot> snp,
    logalloc::region& region,
    logalloc::allocating_section& read_section,
    boost::any pointer_to_container,
    streamed_mutation::forwarding fwd)
{
    return make_partition_snapshot_reader<partition_snapshot_reader_dummy_accounter>(std::move(s),
        std::move(dk), std::move(crr), std::move(snp), region, read_section, std::move(pointer_to_container), fwd);
}
<commit_msg>partition_snapshot_reader: Use rows_entry::position() for comparing rows<commit_after>/*
 * Copyright (C) 2017 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include "partition_version.hh"

struct partition_snapshot_reader_dummy_accounter {
   void operator()(const clustering_row& cr) {}
   void operator()(const static_row& sr) {}
   void operator()(const range_tombstone& rt) {}
};
extern partition_snapshot_reader_dummy_accounter no_accounter;

template <typename MemoryAccounter = partition_snapshot_reader_dummy_accounter>
class partition_snapshot_reader : public streamed_mutation::impl, public MemoryAccounter {
    struct rows_position {
        mutation_partition::rows_type::const_iterator _position;
        mutation_partition::rows_type::const_iterator _end;
    };

    class heap_compare {
        rows_entry::compare _cmp;
    public:
        explicit heap_compare(const schema& s) : _cmp(s) { }
        bool operator()(const rows_position& a, const rows_position& b) {
            return _cmp(*b._position, *a._position);
        }
    };
private:
    // Keeps shared pointer to the container we read mutation from to make sure
    // that its lifetime is appropriately extended.
    boost::any _container_guard;

    query::clustering_key_filter_ranges _ck_ranges;
    query::clustering_row_ranges::const_iterator _current_ck_range;
    query::clustering_row_ranges::const_iterator _ck_range_end;
    bool _in_ck_range = false;

    rows_entry::compare _cmp;
    position_in_partition::equal_compare _eq;
    heap_compare _heap_cmp;

    lw_shared_ptr<partition_snapshot> _snapshot;
    stdx::optional<position_in_partition> _last_entry;

    std::vector<rows_position> _clustering_rows;

    range_tombstone_stream _range_tombstones;

    logalloc::region& _lsa_region;
    logalloc::allocating_section& _read_section;

    MemoryAccounter& mem_accounter() {
        return *this;
    }

    uint64_t _reclaim_counter;
    unsigned _version_count = 0;
private:
    void refresh_iterators() {
        _clustering_rows.clear();

        if (!_in_ck_range && _current_ck_range == _ck_range_end) {
            return;
        }

        for (auto&& v : _snapshot->versions()) {
            auto cr_end = v.partition().upper_bound(*_schema, *_current_ck_range);
            auto cr = [&] () -> mutation_partition::rows_type::const_iterator {
                if (_in_ck_range) {
                    return v.partition().clustered_rows().upper_bound(*_last_entry, _cmp);
                } else {
                    return v.partition().lower_bound(*_schema, *_current_ck_range);
                }
            }();

            if (cr != cr_end) {
                _clustering_rows.emplace_back(rows_position { cr, cr_end });
            }
        }

        _in_ck_range = true;
        boost::range::make_heap(_clustering_rows, _heap_cmp);
    }

    // Valid if has_more_rows()
    const rows_entry& pop_clustering_row() {
        boost::range::pop_heap(_clustering_rows, _heap_cmp);
        auto& current = _clustering_rows.back();
        const rows_entry& e = *current._position;
        current._position = std::next(current._position);
        if (current._position == current._end) {
            _clustering_rows.pop_back();
        } else {
            boost::range::push_heap(_clustering_rows, _heap_cmp);
        }
        return e;
    }

    // Valid if has_more_rows()
    const rows_entry& peek_row() const {
        return *_clustering_rows.front()._position;
    }

    bool has_more_rows() const {
        return !_clustering_rows.empty();
    }

    mutation_fragment_opt read_static_row() {
        _last_entry = position_in_partition(position_in_partition::static_row_tag_t());
        mutation_fragment_opt sr;
        for (auto&& v : _snapshot->versions()) {
            if (!v.partition().static_row().empty()) {
                if (!sr) {
                    sr = mutation_fragment(static_row(v.partition().static_row()));
                } else {
                    sr->as_mutable_static_row().apply(*_schema, v.partition().static_row());
                }
            }
        }
        return sr;
    }

    mutation_fragment_opt read_next() {
        if (has_more_rows()) {
            auto mf = _range_tombstones.get_next(peek_row());
            if (mf) {
                return mf;
            }

            clustering_row result = pop_clustering_row();
            while (has_more_rows() && _eq(peek_row().position(), result.position())) {
                result.apply(*_schema, pop_clustering_row());
            }
            _last_entry = position_in_partition(result.position());
            return mutation_fragment(std::move(result));
        }
        return _range_tombstones.get_next();
    }

    void emplace_mutation_fragment(mutation_fragment&& mfopt) {
        mfopt.visit(mem_accounter());
        push_mutation_fragment(std::move(mfopt));
    }

    void do_fill_buffer() {
        if (!_last_entry) {
            auto mfopt = read_static_row();
            if (mfopt) {
                emplace_mutation_fragment(std::move(*mfopt));
            }
        }

        if (!_in_ck_range || _lsa_region.reclaim_counter() != _reclaim_counter || _snapshot->version_count() != _version_count) {
            refresh_iterators();
            _reclaim_counter = _lsa_region.reclaim_counter();
            _version_count = _snapshot->version_count();
        }

        while (!is_end_of_stream() && !is_buffer_full()) {
            if (_in_ck_range && _clustering_rows.empty()) {
                _in_ck_range = false;
                _current_ck_range = std::next(_current_ck_range);
                refresh_iterators();
                continue;
            }

            auto mfopt = read_next();
            if (mfopt) {
                emplace_mutation_fragment(std::move(*mfopt));
            } else {
                _end_of_stream = true;
            }
        }
    }

    static tombstone tomb(partition_snapshot& snp) {
        tombstone t;
        for (auto& v : snp.versions()) {
            t.apply(v.partition().partition_tombstone());
        }
        return t;
    }
public:
    template <typename... Args>
    partition_snapshot_reader(schema_ptr s, dht::decorated_key dk, lw_shared_ptr<partition_snapshot> snp,
        query::clustering_key_filter_ranges crr,
        logalloc::region& region, logalloc::allocating_section& read_section,
        boost::any pointer_to_container, Args&&... args)
    : streamed_mutation::impl(s, std::move(dk), tomb(*snp))
    , MemoryAccounter(std::forward<Args>(args)...)
    , _container_guard(std::move(pointer_to_container))
    , _ck_ranges(std::move(crr))
    , _current_ck_range(_ck_ranges.begin())
    , _ck_range_end(_ck_ranges.end())
    , _cmp(*s)
    , _eq(*s)
    , _heap_cmp(*s)
    , _snapshot(snp)
    , _range_tombstones(*s)
    , _lsa_region(region)
    , _read_section(read_section) {
        for (auto&& v : _snapshot->versions()) {
            auto&& rt_list = v.partition().row_tombstones();
            for (auto&& range : _ck_ranges.ranges()) {
                _range_tombstones.apply(rt_list, range);
            }
        }
        do_fill_buffer();
    }

    ~partition_snapshot_reader() {
        if (!_snapshot.owned()) {
            return;
        }
        // If no one else is using this particular snapshot try to merge partition
        // versions.
        with_allocator(_lsa_region.allocator(), [this] {
            return with_linearized_managed_bytes([this] {
                try {
                    _read_section(_lsa_region, [this] {
                        _snapshot->merge_partition_versions();
                    });
                } catch (...) { }
                _snapshot = {};
            });
        });
    }

    virtual future<> fill_buffer() override {
        return _read_section(_lsa_region, [&] {
            return with_linearized_managed_bytes([&] {
                do_fill_buffer();
                return make_ready_future<>();
            });
        });
    }
};

template <typename MemoryAccounter, typename... Args>
inline streamed_mutation
make_partition_snapshot_reader(schema_ptr s,
    dht::decorated_key dk,
    query::clustering_key_filter_ranges crr,
    lw_shared_ptr<partition_snapshot> snp,
    logalloc::region& region,
    logalloc::allocating_section& read_section,
    boost::any pointer_to_container,
    streamed_mutation::forwarding fwd,
    Args&&... args)
{
    auto sm = make_streamed_mutation<partition_snapshot_reader<MemoryAccounter>>(s, std::move(dk),
           snp, std::move(crr), region, read_section, std::move(pointer_to_container), std::forward<Args>(args)...);
    if (fwd) {
        return make_forwardable(std::move(sm)); // FIXME: optimize
    } else {
        return std::move(sm);
    }
}

inline streamed_mutation
make_partition_snapshot_reader(schema_ptr s,
    dht::decorated_key dk,
    query::clustering_key_filter_ranges crr,
    lw_shared_ptr<partition_snapshot> snp,
    logalloc::region& region,
    logalloc::allocating_section& read_section,
    boost::any pointer_to_container,
    streamed_mutation::forwarding fwd)
{
    return make_partition_snapshot_reader<partition_snapshot_reader_dummy_accounter>(std::move(s),
        std::move(dk), std::move(crr), std::move(snp), region, read_section, std::move(pointer_to_container), fwd);
}
<|endoftext|>


<commit_before>#include <iostream>
#include <boost/lexical_cast.hpp>

#include "Mesh.h"
#include "Model.h"
#include "PnPProblem.h"
#include "RobustMatcher.h"
#include "ModelRegistration.h"
#include "Utils.h"

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/nonfree/features2d.hpp>

  /*
   * Set up the images paths
   */

  // COOKIES BOX [718x480]
  std::string img_path = "../Data/resized_IMG_3875.JPG"; // f 55

  // COOKIES BOX MESH
  std::string ply_read_path = "../Data/box.ply";

  // YAML writting path
  std::string write_path = "../Data/cookies_ORB.yml";

  // Boolean the know if the registration it's done
  bool end_registration = false;

  /*
   * Set up the intrinsic camera parameters: CANON
   */
  double f = 45; // focal length in mm
  double sx = 22.3, sy = 14.9;
  double width = 2592, height = 1944;
  double params_CANON[] = { width*f/sx,   // fx
                            height*f/sy,  // fy
                            width/2,      // cx
                            height/2};    // cy

  // Setup the points to register in the image
  // In the order of the *.ply file and starting at 1
  int n = 8;
  int pts[] = {1, 2, 3, 4, 5, 6, 7, 8}; // 3 -> 4

  /*
   * Set up some basic colors
   */
  cv::Scalar red(0, 0, 255);
  cv::Scalar green(0,255,0);
  cv::Scalar blue(255,0,0);
  cv::Scalar yellow(0,255,255);

  /*
   * CREATE MODEL REGISTRATION OBJECT
   * CREATE OBJECT MESH
   * CREATE OBJECT MODEL
   * CREATE PNP OBJECT
   */
  ModelRegistration registration;
  Model model;
  Mesh mesh;
  PnPProblem pnp_registration(params_CANON);

// Mouse events for model registration
static void onMouseModelRegistration( int event, int x, int y, int, void* )
{
  if  ( event == cv::EVENT_LBUTTONUP )
  {
      int n_regist = registration.getNumRegist();
      int n_vertex = pts[n_regist];

      cv::Point2f point_2d = cv::Point2f(x,y);
      cv::Point3f point_3d = mesh.getVertex(n_vertex-1);

      bool is_registrable = registration.is_registrable();
      if (is_registrable)
      {
        registration.registerPoint(point_2d, point_3d);
        if( registration.getNumRegist() == registration.getNumMax() ) end_registration = true;
      }
  }
}

/*
 *   MAIN PROGRAM
 *
 */

int main(int argc, char *argv[])
{

  std::cout << "!!!Hello Registration!!!" << std::endl;

  // load a mesh given the *.ply file path
  mesh.load(ply_read_path);

  // set parameters
  int numKeyPoints = 10000;

  //Instantiate robust matcher: detector, extractor, matcher
  RobustMatcher rmatcher;
  cv::FeatureDetector * detector = new cv::OrbFeatureDetector(numKeyPoints);
  //rmatcher.setFeatureDetector(detector);

  /*
   * GROUND TRUTH OF THE FIRST IMAGE
   *
   * by the moment it is the reference image
   */

  // Create & Open Window
  cv::namedWindow("MODEL REGISTRATION", cv::WINDOW_KEEPRATIO);

  // Set up the mouse events
  cv::setMouseCallback("MODEL REGISTRATION", onMouseModelRegistration, 0 );

  // Open the image to register
  cv::Mat img_in = cv::imread(img_path, cv::IMREAD_COLOR);
  cv::Mat img_vis = img_in.clone();

  if (!img_in.data) {
    std::cout << "Could not open or find the image" << std::endl;
    return -1;
  }

  // Set the number of points to register
  int num_registrations = n;
  registration.setNumMax(num_registrations);

  std::cout << "Click the box corners ..." << std::endl;
  std::cout << "Waiting ..." << std::endl;

  // Loop until all the points are registered
  while ( cv::waitKey(30) < 0 )
  {
    // Refresh debug image
    img_vis = img_in.clone();

    // Current registered points
    std::vector<cv::Point2f> list_points2d = registration.get_points2d();
    std::vector<cv::Point3f> list_points3d = registration.get_points3d();

    // Draw current registered points
    drawPoints(img_vis, list_points2d, list_points3d, red);

    // If the registration is not finished, draw which 3D point we have to register.
    // If the registration is finished, breaks the loop.
    if (!end_registration)
    {
      // Draw debug text
      int n_regist = registration.getNumRegist();
      int n_vertex = pts[n_regist];
      cv::Point3f current_poin3d = mesh.getVertex(n_vertex-1);

      drawQuestion(img_vis, current_poin3d, green);
      drawCounter(img_vis, registration.getNumRegist(), registration.getNumMax(), red);
    }
    else
    {
      // Draw debug text
      drawText(img_vis, "END REGISTRATION", green);
      drawCounter(img_vis, registration.getNumRegist(), registration.getNumMax(), green);
      break;
    }

    // Show the image
    cv::imshow("MODEL REGISTRATION", img_vis);
  }

  /*
   *
   * COMPUTE CAMERA POSE
   *
   */

  std::cout << "COMPUTING POSE ..." << std::endl;

  // The list of registered points
  std::vector<cv::Point2f> list_points2d = registration.get_points2d();
  std::vector<cv::Point3f> list_points3d = registration.get_points3d();

  // Estimate pose given the registered points
  bool is_correspondence = pnp_registration.estimatePose(list_points3d, list_points2d, cv::ITERATIVE);
  if ( is_correspondence )
  {
    std::cout << "Correspondence found" << std::endl;

    // Compute all the 2D points of the mesh to verify the algorithm and draw it
    std::vector<cv::Point2f> list_points2d_mesh = pnp_registration.verify_points(&mesh);
    draw2DPoints(img_vis, list_points2d_mesh, green);

  } else {
    std::cout << "Correspondence not found" << std::endl << std::endl;
  }

  // Show the image
  cv::imshow("MODEL REGISTRATION", img_vis);

  // Show image until ESC pressed
  cv::waitKey(0);

   /*
    *
    * COMPUTE 3D of the image Keypoints
    *
    */

  // Containers for keypoints and descriptors of the model
  std::vector<cv::KeyPoint> keypoints_model;
  cv::Mat descriptors;

  // Compute keypoints and descriptors
  rmatcher.computeKeyPoints(img_in, keypoints_model);
  rmatcher.computeDescriptors(img_in, keypoints_model, descriptors);

  // Check if keypoints are on the surface of the registration image and add to the model
  for (unsigned int i = 0; i < keypoints_model.size(); ++i) {
    cv::Point2f point2d(keypoints_model[i].pt);
    cv::Point3f point3d;
    bool on_surface = pnp_registration.backproject2DPoint(&mesh, point2d, point3d);
    if (on_surface)
    {
        model.add_correspondence(point2d, point3d);
        model.add_descriptor(descriptors.row(i));
        model.add_keypoint(keypoints_model[i]);
    }
    else
    {
        model.add_outlier(point2d);
    }
  }

  // save the model into a *.yaml file
  model.save(write_path);

  // Out image
  img_vis = img_in.clone();

  // The list of the points2d of the model
  std::vector<cv::Point2f> list_points_in = model.get_points2d_in();
  std::vector<cv::Point2f> list_points_out = model.get_points2d_out();

  // Draw some debug text
  std::string num = boost::lexical_cast< std::string >(list_points_in.size());
  std::string text = "There are " + num + " inliers";
  drawText(img_vis, text, green);

  // Draw some debug text
  num = boost::lexical_cast< std::string >(list_points_out.size());
  text = "There are " + num + " outliers";
  drawText2(img_vis, text, red);

  // Draw the object mesh
  drawObjectMesh(img_vis, &mesh, &pnp_registration, blue);

  // Draw found keypoints depending on if are or not on the surface
  draw2DPoints(img_vis, list_points_in, green);
  draw2DPoints(img_vis, list_points_out, red);

  // Show the image
  cv::imshow("MODEL REGISTRATION", img_vis);

  // Wait until ESC pressed
  cv::waitKey(0);

  // Close and Destroy Window
  cv::destroyWindow("MODEL REGISTRATION");

  std::cout << "GOODBYE" << std::endl;

}
<commit_msg>Added help()<commit_after>#include <iostream>
#include <boost/lexical_cast.hpp>

#include "Mesh.h"
#include "Model.h"
#include "PnPProblem.h"
#include "RobustMatcher.h"
#include "ModelRegistration.h"
#include "Utils.h"

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/nonfree/features2d.hpp>

  /*
   * Set up the images paths
   */

  // COOKIES BOX [718x480]
  std::string img_path = "../Data/resized_IMG_3875.JPG"; // f 55

  // COOKIES BOX MESH
  std::string ply_read_path = "../Data/box.ply";

  // YAML writting path
  std::string write_path = "../Data/cookies_ORB.yml";

  void help()
  {
  std::cout
  << "--------------------------------------------------------------------------"   << std::endl
  << "This program shows how to create your 3D textured model. "                    << std::endl
  << "Usage:"                                                                       << std::endl
  << "./pnp_registration "                                                          << std::endl
  << "--------------------------------------------------------------------------"   << std::endl
  << std::endl;
  }

  // Boolean the know if the registration it's done
  bool end_registration = false;

  /*
   * Set up the intrinsic camera parameters: CANON
   */
  double f = 45; // focal length in mm
  double sx = 22.3, sy = 14.9;
  double width = 2592, height = 1944;
  double params_CANON[] = { width*f/sx,   // fx
                            height*f/sy,  // fy
                            width/2,      // cx
                            height/2};    // cy

  // Setup the points to register in the image
  // In the order of the *.ply file and starting at 1
  int n = 8;
  int pts[] = {1, 2, 3, 4, 5, 6, 7, 8}; // 3 -> 4

  /*
   * Set up some basic colors
   */
  cv::Scalar red(0, 0, 255);
  cv::Scalar green(0,255,0);
  cv::Scalar blue(255,0,0);
  cv::Scalar yellow(0,255,255);

  /*
   * CREATE MODEL REGISTRATION OBJECT
   * CREATE OBJECT MESH
   * CREATE OBJECT MODEL
   * CREATE PNP OBJECT
   */
  ModelRegistration registration;
  Model model;
  Mesh mesh;
  PnPProblem pnp_registration(params_CANON);

// Mouse events for model registration
static void onMouseModelRegistration( int event, int x, int y, int, void* )
{
  if  ( event == cv::EVENT_LBUTTONUP )
  {
      int n_regist = registration.getNumRegist();
      int n_vertex = pts[n_regist];

      cv::Point2f point_2d = cv::Point2f(x,y);
      cv::Point3f point_3d = mesh.getVertex(n_vertex-1);

      bool is_registrable = registration.is_registrable();
      if (is_registrable)
      {
        registration.registerPoint(point_2d, point_3d);
        if( registration.getNumRegist() == registration.getNumMax() ) end_registration = true;
      }
  }
}

/*
 *   MAIN PROGRAM
 *
 */

int main(int argc, char *argv[])
{

  help();

  // load a mesh given the *.ply file path
  mesh.load(ply_read_path);

  // set parameters
  int numKeyPoints = 10000;

  //Instantiate robust matcher: detector, extractor, matcher
  RobustMatcher rmatcher;
  cv::FeatureDetector * detector = new cv::OrbFeatureDetector(numKeyPoints);
  rmatcher.setFeatureDetector(detector);

  /*
   * GROUND TRUTH OF THE FIRST IMAGE
   *
   * by the moment it is the reference image
   */

  // Create & Open Window
  cv::namedWindow("MODEL REGISTRATION", cv::WINDOW_KEEPRATIO);

  // Set up the mouse events
  cv::setMouseCallback("MODEL REGISTRATION", onMouseModelRegistration, 0 );

  // Open the image to register
  cv::Mat img_in = cv::imread(img_path, cv::IMREAD_COLOR);
  cv::Mat img_vis = img_in.clone();

  if (!img_in.data) {
    std::cout << "Could not open or find the image" << std::endl;
    return -1;
  }

  // Set the number of points to register
  int num_registrations = n;
  registration.setNumMax(num_registrations);

  std::cout << "Click the box corners ..." << std::endl;
  std::cout << "Waiting ..." << std::endl;

  // Loop until all the points are registered
  while ( cv::waitKey(30) < 0 )
  {
    // Refresh debug image
    img_vis = img_in.clone();

    // Current registered points
    std::vector<cv::Point2f> list_points2d = registration.get_points2d();
    std::vector<cv::Point3f> list_points3d = registration.get_points3d();

    // Draw current registered points
    drawPoints(img_vis, list_points2d, list_points3d, red);

    // If the registration is not finished, draw which 3D point we have to register.
    // If the registration is finished, breaks the loop.
    if (!end_registration)
    {
      // Draw debug text
      int n_regist = registration.getNumRegist();
      int n_vertex = pts[n_regist];
      cv::Point3f current_poin3d = mesh.getVertex(n_vertex-1);

      drawQuestion(img_vis, current_poin3d, green);
      drawCounter(img_vis, registration.getNumRegist(), registration.getNumMax(), red);
    }
    else
    {
      // Draw debug text
      drawText(img_vis, "END REGISTRATION", green);
      drawCounter(img_vis, registration.getNumRegist(), registration.getNumMax(), green);
      break;
    }

    // Show the image
    cv::imshow("MODEL REGISTRATION", img_vis);
  }

  /*
   *
   * COMPUTE CAMERA POSE
   *
   */

  std::cout << "COMPUTING POSE ..." << std::endl;

  // The list of registered points
  std::vector<cv::Point2f> list_points2d = registration.get_points2d();
  std::vector<cv::Point3f> list_points3d = registration.get_points3d();

  // Estimate pose given the registered points
  bool is_correspondence = pnp_registration.estimatePose(list_points3d, list_points2d, cv::ITERATIVE);
  if ( is_correspondence )
  {
    std::cout << "Correspondence found" << std::endl;

    // Compute all the 2D points of the mesh to verify the algorithm and draw it
    std::vector<cv::Point2f> list_points2d_mesh = pnp_registration.verify_points(&mesh);
    draw2DPoints(img_vis, list_points2d_mesh, green);

  } else {
    std::cout << "Correspondence not found" << std::endl << std::endl;
  }

  // Show the image
  cv::imshow("MODEL REGISTRATION", img_vis);

  // Show image until ESC pressed
  cv::waitKey(0);

   /*
    *
    * COMPUTE 3D of the image Keypoints
    *
    */

  // Containers for keypoints and descriptors of the model
  std::vector<cv::KeyPoint> keypoints_model;
  cv::Mat descriptors;

  // Compute keypoints and descriptors
  rmatcher.computeKeyPoints(img_in, keypoints_model);
  rmatcher.computeDescriptors(img_in, keypoints_model, descriptors);

  // Check if keypoints are on the surface of the registration image and add to the model
  for (unsigned int i = 0; i < keypoints_model.size(); ++i) {
    cv::Point2f point2d(keypoints_model[i].pt);
    cv::Point3f point3d;
    bool on_surface = pnp_registration.backproject2DPoint(&mesh, point2d, point3d);
    if (on_surface)
    {
        model.add_correspondence(point2d, point3d);
        model.add_descriptor(descriptors.row(i));
        model.add_keypoint(keypoints_model[i]);
    }
    else
    {
        model.add_outlier(point2d);
    }
  }

  // save the model into a *.yaml file
  model.save(write_path);

  // Out image
  img_vis = img_in.clone();

  // The list of the points2d of the model
  std::vector<cv::Point2f> list_points_in = model.get_points2d_in();
  std::vector<cv::Point2f> list_points_out = model.get_points2d_out();

  // Draw some debug text
  std::string num = boost::lexical_cast< std::string >(list_points_in.size());
  std::string text = "There are " + num + " inliers";
  drawText(img_vis, text, green);

  // Draw some debug text
  num = boost::lexical_cast< std::string >(list_points_out.size());
  text = "There are " + num + " outliers";
  drawText2(img_vis, text, red);

  // Draw the object mesh
  drawObjectMesh(img_vis, &mesh, &pnp_registration, blue);

  // Draw found keypoints depending on if are or not on the surface
  draw2DPoints(img_vis, list_points_in, green);
  draw2DPoints(img_vis, list_points_out, red);

  // Show the image
  cv::imshow("MODEL REGISTRATION", img_vis);

  // Wait until ESC pressed
  cv::waitKey(0);

  // Close and Destroy Window
  cv::destroyWindow("MODEL REGISTRATION");

  std::cout << "GOODBYE" << std::endl;

}
<|endoftext|>


<commit_before>/*
 * exprtree.cpp
 *
 *  Created on: Jan 14, 2015
 *      Author: radoslav
 */

#include "exprtree.h"
#include "arithmetic.h"
#include "token.h"
#include "operator.h"
#include "lambda.h"
#include "integer.h"
#include "string.h"
#include "identifier.h"
#include "strtok.h"
#include "call.h"
#include "environment.h"
#include <cstdlib>
#include <cstring>
#include <vector>
#include <map>
#include <stack>

void ExpressionTreeNode::copy(const ExpressionTreeNode& other)
{
	value = other.value->clone();
	left = other.left;
	right = other.right;
}

void ExpressionTreeNode::destroy()
{
	delete value;
}

ExpressionTreeNode::ExpressionTreeNode(const ExpressionTreeNode& other)
{
	copy(other);
}

ExpressionTreeNode& ExpressionTreeNode::operator=(const ExpressionTreeNode& other)
{
	if (&other != this)
	{
		destroy();
		copy(other);
	}

	return *this;
}

ExpressionTreeNode::~ExpressionTreeNode()
{
	destroy();
}

void ExpressionTree::createTree(std::stack<ExpressionTree>& rstack, char op)
{
	ExpressionTree rtree = rstack.top();
	rstack.pop();
	ExpressionTree ltree = rstack.top();
	rstack.pop();

	rstack.push(ExpressionTree(new Operator(op), ltree, rtree));
}

Value* ExpressionTree::evaluateExpression(ExpressionTreeConstIterator it, Environment& environment)
{
	switch ((*it)->getTokenType())
	{
	case TOKEN_VALUE:
		// листо
		switch (((Value*) (*it))->getValueType())
		{
		case VALUE_IDENTIFIER:
			return environment[*((Identifier*) (*it))];

		case VALUE_CALL:
			return ((Call*) (*it))->execute(environment);

		default:
			return (Value*) *it;
		}
		break;

	case TOKEN_OPERATOR:
		{
			Value *lhs = evaluateExpression(++it, environment), *rhs = evaluateExpression(it++, environment);

			if (lhs->getValueType() == VALUE_INTEGER && rhs->getValueType() == VALUE_INTEGER)
			{
				int lhs_val = ((Integer*) lhs)->getInteger(), rhs_val = ((Integer*) rhs)->getInteger();

				switch (((Operator*) (*it))->getOperator())
				{
					case '+': return new Integer(lhs_val + rhs_val);
					case '-': return new Integer(lhs_val - rhs_val);
					case '*': return new Integer(lhs_val * rhs_val);
					case '/': return new Integer(lhs_val / rhs_val);
					case '^': return new Integer(ipow(lhs_val, rhs_val));
					default:  return 0;
				}
			}
			else if (lhs->getValueType() == VALUE_STRING && rhs->getValueType() == VALUE_STRING)
			{
				std::string lhs_val = ((String*) lhs)->getString(), rhs_val = ((String*) rhs)->getString();
				return ((Operator*) (*it))->getOperator() == '+' ? new String(lhs_val + rhs_val) : new String();
			}
		}
		break;

	default:;
	}

	return NULL;
}

ExpressionTree ExpressionTree::createExpressionTree(const char*& expr)
{
	std::stack<char> opstack;
	std::stack<ExpressionTree> rstack;

	if (!expr)
		return ExpressionTree();

	while (*expr && *expr != ';' && *expr != ',' && *expr != ')')
    {
		if (*expr >= '0' && *expr <= '9' || *expr == '-' && expr + 1 && *(expr + 1) >= '0' && *(expr + 1) <= '9')
			rstack.push(ExpressionTree(new Integer(expr)));
		else if (*expr == '"')
			rstack.push(ExpressionTree(new String(expr)));
		else if (*expr == '\\')
			rstack.push(ExpressionTree(new Lambda(expr)));
		else if (*expr >= 'A' && *expr <= 'Z' || *expr >= 'a' && *expr <= 'z')
		{
			const char* name = expr;
			Identifier id(name);

			if (!id.getName().empty())
				rstack.push(ExpressionTree(gotoToken(name, " \t\n\r") && *name == '(' ? (Token*) new Call(expr) : (Token*) new Identifier(expr)));
		}
		else
		{
			if (*expr == '(')
				opstack.push(*expr);
			else if (*expr == ')')
			{
				char op = opstack.top();
				opstack.pop();

				while (op != '(')
				{
					createTree(rstack, op);
					op = opstack.top();
					opstack.pop();
				}
			}
			else if (*expr != ' ' && *expr != '\t' && *expr != '\n' && *expr != '\r')
			{
				// *expr е операция
				// първо: вадим всички операции
				// с по-висок или равен приоритет
				while (!opstack.empty() && priority(opstack.top()) >= priority(*expr))
				{
					createTree(rstack, opstack.top());
					opstack.pop();
				}

				opstack.push(*expr);
			}

			expr++;
		}
	}

	while (!opstack.empty())
	{
		createTree(rstack, opstack.top());
		opstack.pop();
	}

	return rstack.top();
}

void ExpressionTree::deleteNode(ExpressionTreeNode* node)
{
	if (node)
	{
		deleteNode(node->left);
		deleteNode(node->right);
		delete node;
	}
}

ExpressionTreeNode* ExpressionTree::copyNode(ExpressionTreeNode* node)
{
	return node ? new ExpressionTreeNode(node->value, true, copyNode(node->left), copyNode(node->right)) : NULL;
}

ExpressionTree::ExpressionTree(Token* value, ExpressionTree& left, ExpressionTree& right, bool doClone)
{
	root = new ExpressionTreeNode(value, doClone);
	adoptLeft(left.root);
	adoptRight(right.root);
}

ExpressionTree::ExpressionTree(const ExpressionTree& other)
{
	root = copyNode(other.root);
}

ExpressionTree& ExpressionTree::operator=(const ExpressionTree& other)
{
	if (&other != this)
	{
		deleteNode(root);
		root = copyNode(other.root);
	}

	return *this;
}

ExpressionTree::~ExpressionTree()
{
	deleteNode(root);
}

<commit_msg>fixed problems with attemptingo to deallocate memory through an invalid pointer by guaranteeing that these pointers are never invalidated: when a pointer is returned, it refers to a new object (either created through `new' + constructor or cloned); similarly, objects created this way in the body of a function which are not returned are deleted at the end of their use<commit_after>/*
 * exprtree.cpp
 *
 *  Created on: Jan 14, 2015
 *      Author: radoslav
 */

#include "exprtree.h"
#include "arithmetic.h"
#include "token.h"
#include "operator.h"
#include "lambda.h"
#include "integer.h"
#include "string.h"
#include "identifier.h"
#include "strtok.h"
#include "call.h"
#include "environment.h"
#include "value.h"
#include <cstdlib>
#include <cstring>
#include <vector>
#include <map>
#include <stack>

void ExpressionTreeNode::copy(const ExpressionTreeNode& other)
{
	value = other.value->clone();
	left = other.left;
	right = other.right;
}

void ExpressionTreeNode::destroy()
{
	delete value;
}

ExpressionTreeNode::ExpressionTreeNode(const ExpressionTreeNode& other)
{
	copy(other);
}

ExpressionTreeNode& ExpressionTreeNode::operator=(const ExpressionTreeNode& other)
{
	if (&other != this)
	{
		destroy();
		copy(other);
	}

	return *this;
}

ExpressionTreeNode::~ExpressionTreeNode()
{
	destroy();
}

void ExpressionTree::createTree(std::stack<ExpressionTree>& rstack, char op)
{
	ExpressionTree rtree = rstack.top();
	rstack.pop();
	ExpressionTree ltree = rstack.top();
	rstack.pop();

	rstack.push(ExpressionTree(new Operator(op), ltree, rtree));
}

Value* ExpressionTree::evaluateExpression(ExpressionTreeConstIterator it, Environment& environment)
{
	switch ((*it)->getTokenType())
	{
	case TOKEN_VALUE:
		// листо
		switch (((Value*) (*it))->getValueType())
		{
		case VALUE_IDENTIFIER:
			return environment[*((Identifier*) (*it))]->clone();

		case VALUE_CALL:
			return ((Call*) (*it))->execute(environment);

		default:
			return ((Value*) *it)->clone();
		}
		break;

	case TOKEN_OPERATOR:
		{
			Value *lhs = evaluateExpression(++it, environment), *rhs = evaluateExpression(it++, environment);

			if (lhs->getValueType() == VALUE_INTEGER && rhs->getValueType() == VALUE_INTEGER)
			{
				int lhs_val = ((Integer*) lhs)->getInteger(), rhs_val = ((Integer*) rhs)->getInteger();

				switch (((Operator*) (*it))->getOperator())
				{
					case '+': return new Integer(lhs_val + rhs_val);
					case '-': return new Integer(lhs_val - rhs_val);
					case '*': return new Integer(lhs_val * rhs_val);
					case '/': return new Integer(lhs_val / rhs_val);
					case '^': return new Integer(ipow(lhs_val, rhs_val));
					default:  return NULL;
				}
			}
			else if (lhs->getValueType() == VALUE_STRING && rhs->getValueType() == VALUE_STRING)
			{
				std::string lhs_val = ((String*) lhs)->getString(), rhs_val = ((String*) rhs)->getString();
				return ((Operator*) (*it))->getOperator() == '+' ? new String(lhs_val + rhs_val) : new String();
			}

			delete lhs;
			delete rhs;
		}
		break;

	default:;
	}

	return NULL;
}

ExpressionTree ExpressionTree::createExpressionTree(const char*& expr)
{
	std::stack<char> opstack;
	std::stack<ExpressionTree> rstack;

	if (!expr)
		return ExpressionTree();

	while (*expr && *expr != ';' && *expr != ',' && *expr != ')')
    {
		if (*expr >= '0' && *expr <= '9' || *expr == '-' && expr + 1 && *(expr + 1) >= '0' && *(expr + 1) <= '9')
			rstack.push(ExpressionTree(new Integer(expr)));
		else if (*expr == '"')
			rstack.push(ExpressionTree(new String(expr)));
		else if (*expr == '\\')
			rstack.push(ExpressionTree(new Lambda(expr)));
		else if (*expr >= 'A' && *expr <= 'Z' || *expr >= 'a' && *expr <= 'z')
		{
			const char* name = expr;
			Identifier id(name);

			if (!id.getName().empty())
				rstack.push(ExpressionTree(gotoToken(name, " \t\n\r") && *name == '(' ? (Token*) new Call(expr) : (Token*) new Identifier(expr)));
		}
		else
		{
			if (*expr == '(')
				opstack.push(*expr);
			else if (*expr == ')')
			{
				char op = opstack.top();
				opstack.pop();

				while (op != '(')
				{
					createTree(rstack, op);
					op = opstack.top();
					opstack.pop();
				}
			}
			else if (*expr != ' ' && *expr != '\t' && *expr != '\n' && *expr != '\r')
			{
				// *expr е операция
				// първо: вадим всички операции
				// с по-висок или равен приоритет
				while (!opstack.empty() && priority(opstack.top()) >= priority(*expr))
				{
					createTree(rstack, opstack.top());
					opstack.pop();
				}

				opstack.push(*expr);
			}

			expr++;
		}
	}

	while (!opstack.empty())
	{
		createTree(rstack, opstack.top());
		opstack.pop();
	}

	return rstack.top();
}

void ExpressionTree::deleteNode(ExpressionTreeNode* node)
{
	if (node)
	{
		deleteNode(node->left);
		deleteNode(node->right);
		delete node;
	}
}

ExpressionTreeNode* ExpressionTree::copyNode(ExpressionTreeNode* node)
{
	return node ? new ExpressionTreeNode(node->value, true, copyNode(node->left), copyNode(node->right)) : NULL;
}

ExpressionTree::ExpressionTree(Token* value, ExpressionTree& left, ExpressionTree& right, bool doClone)
{
	root = new ExpressionTreeNode(value, doClone);
	adoptLeft(left.root);
	adoptRight(right.root);
}

ExpressionTree::ExpressionTree(const ExpressionTree& other)
{
	root = copyNode(other.root);
}

ExpressionTree& ExpressionTree::operator=(const ExpressionTree& other)
{
	if (&other != this)
	{
		deleteNode(root);
		root = copyNode(other.root);
	}

	return *this;
}

ExpressionTree::~ExpressionTree()
{
	deleteNode(root);
}

<|endoftext|>


<commit_before>//
// Copyright (C) 2014, 2015 Ableton AG, Berlin. All rights reserved.
//
// 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.
//

/*!
 * @file
 */

#pragma once

#include <atria/estd/utility.hpp>
#include <atria/estd/type_traits.hpp>
#include <atria/prelude/tuplify.hpp>

namespace atria {
namespace xform {

/*!
 * Reducing function that emplaces back at the collection that is
 * uses as state.
 */
constexpr struct last_rf_t
{
  template <typename StateT, typename ...InputTs>
  constexpr auto operator() (StateT&&, InputTs&& ...ins) const
    -> estd::decay_t<decltype(tuplify(std::forward<InputTs>(ins)...))>
  {
    return tuplify(std::forward<InputTs>(ins)...);
  }

  template <typename StateT, typename ...InputTs>
  constexpr auto operator() (StateT&& s) const
    -> StateT&&
  {
    return std::forward<StateT>(s);
  }
} last_rf {};

} // namespace xform
} // namespace atria
<commit_msg>xform: fix `last_rf` for no arguments<commit_after>//
// Copyright (C) 2014, 2015 Ableton AG, Berlin. All rights reserved.
//
// 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.
//

/*!
 * @file
 */

#pragma once

#include <atria/estd/utility.hpp>
#include <atria/estd/type_traits.hpp>
#include <atria/prelude/tuplify.hpp>

namespace atria {
namespace xform {

/*!
 * Reducing function that produces the tuplification of the last
 * inputs it received.
 *
 * @see tuplify
 */
constexpr struct last_rf_t
{
  template <typename StateT, typename ...InputTs>
  constexpr auto operator() (StateT&&, InputTs&& ...ins) const
    -> estd::decay_t<decltype(tuplify(std::forward<InputTs>(ins)...))>
  {
    return tuplify(std::forward<InputTs>(ins)...);
  }
} last_rf {};

} // namespace xform
} // namespace atria
<|endoftext|>


<commit_before>#include <errno.h>

#include "rgw_common.h"
#include "rgw_acl.h"

#include "common/ceph_crypto.h"

using namespace ceph::crypto;

/* Loglevel of the gateway */
int rgw_log_level = 20;

int parse_time(const char *time_str, time_t *time)
{
  struct tm tm;
  memset(&tm, 0, sizeof(struct tm));
  if (!strptime(time_str, "%a, %d %b %Y %H:%M:%S %Z", &tm))
    return -EINVAL;

  *time = mktime(&tm);

  return 0;
}

/*
 * calculate the sha1 value of a given msg and key
 */
void calc_hmac_sha1(const char *key, int key_len,
                    const char *msg, int msg_len, char *dest)
/* destination should be CEPH_CRYPTO_HMACSHA1_DIGESTSIZE bytes long */
{
  char key_buf[CEPH_CRYPTO_HMACSHA1_DIGESTSIZE];
  memset(key_buf, 0, CEPH_CRYPTO_HMACSHA1_DIGESTSIZE);
  memcpy(key_buf, key, key_len);

  HMACSHA1 hmac((const unsigned char *)key, key_len);
  hmac.Update((const unsigned char *)msg, msg_len);
  hmac.Final((unsigned char *)dest);

  char hex_str[(CEPH_CRYPTO_HMACSHA1_DIGESTSIZE * 2) + 1];
  buf_to_hex((unsigned char *)dest, CEPH_CRYPTO_HMACSHA1_DIGESTSIZE, hex_str);

  RGW_LOG(15) << "hmac=" << hex_str << endl;
}

int NameVal::parse()
{
  int delim_pos = str.find('=');
  int ret = 0;

  if (delim_pos < 0) {
    name = str;
    val = "";
    ret = 1;
  } else {
    name = str.substr(0, delim_pos);
    val = str.substr(delim_pos + 1);
  }

  RGW_LOG(10) << "parsed: name=" << name << " val=" << val << endl;
  return ret;
}

int XMLArgs::parse()
{
  int pos = 0, fpos;
  bool end = false;
  if (str[pos] == '?') pos++;

  while (!end) {
    fpos = str.find('&', pos);
    if (fpos  < pos) {
       end = true;
       fpos = str.size();
    }
    NameVal nv(str.substr(pos, fpos - pos));
    int ret = nv.parse();
    if (ret >= 0) {
      val_map[nv.get_name()] = nv.get_val();

      if (ret > 0) { /* this might be a sub-resource */
        if ((nv.get_name().compare("acl") == 0) ||
            (nv.get_name().compare("location") == 0) ||
            (nv.get_name().compare("torrent") == 0))
          sub_resource = nv.get_name();
      }
    }

    pos = fpos + 1;
  }

  return 0;
}

string& XMLArgs::get(string& name)
{
  map<string, string>::iterator iter;
  iter = val_map.find(name);
  if (iter == val_map.end())
    return empty_str;
  return iter->second;
}

string& XMLArgs::get(const char *name)
{
  string s(name);
  return get(s);
}

bool verify_permission(RGWAccessControlPolicy *policy, string& uid, int perm)
{
   if (!policy)
     return false;

   int acl_perm = policy->get_perm(uid, perm);

   return (perm == acl_perm);
}

bool verify_permission(struct req_state *s, int perm)
{
  return verify_permission(s->acl, s->user.user_id, perm);
}

static char hex_to_num(char c)
{
  static char table[256];
  static bool initialized = false;

  if (!initialized) {
    memset(table, -1, sizeof(table));
    int i;
    for (i = '0'; i<='9'; i++)
      table[i] = i - '0';
    for (i = 'A'; i<='F'; i++)
      table[i] = i - 'A' + 0xa;
    for (i = 'a'; i<='f'; i++)
      table[i] = i - 'a' + 0xa;
  }
  return table[(int)c];
}

bool url_decode(string& src_str, string& dest_str)
{
  RGW_LOG(10) << "in url_decode with " << src_str << endl;
  const char *src = src_str.c_str();
  char dest[src_str.size()];
  int pos = 0;
  char c;

  RGW_LOG(10) << "src=" << (void *)src << std::endl;

  while (*src) {
    if (*src != '%') {
      if (*src != '+') {
	dest[pos++] = *src++;
      } else {
	dest[pos++] = ' ';
	++src;
      }
    } else {
      src++;
      char c1 = hex_to_num(*src++);
      c = c1 << 4;
      if (c1 < 0)
        return false;
      c1 = hex_to_num(*src++);
      if (c1 < 0)
        return false;
      c |= c1;
      dest[pos++] = c;
    }
  }
  dest[pos] = 0;
  dest_str = dest;

  return true;
}

void RGWFormatter::write_data(const char *fmt, ...)
{
#define LARGE_ENOUGH_LEN 128
  int n, size = LARGE_ENOUGH_LEN;
  char s[size];
  char *p, *np;
  bool p_on_stack;
  va_list ap;
  int pos;

  p = s;
  p_on_stack = true;

  while (1) {
    va_start(ap, fmt);
    n = vsnprintf(p, size, fmt, ap);
    va_end(ap);

    if (n > -1 && n < size)
      goto done;
    /* Else try again with more space. */
    if (n > -1)    /* glibc 2.1 */
      size = n+1; /* precisely what is needed */
    else           /* glibc 2.0 */
      size *= 2;  /* twice the old size */
    if (p_on_stack)
      np = (char *)malloc(size);
    else
      np = (char *)realloc(p, size);
    if (!np)
      goto done_free;
    p = np;
    p_on_stack = false;
  }
done:
#define LARGE_ENOUGH_BUF 4096
  if (!buf) {
    max_len = max(LARGE_ENOUGH_BUF, size);
    buf = (char *)malloc(max_len);
  }

  if (len + size > max_len) {
    max_len = len + size + LARGE_ENOUGH_BUF;
    buf = (char *)realloc(buf, max_len);
  }
  if (!buf) {
    RGW_LOG(0) << "RGWFormatter::write_data: failed allocating " << max_len << " bytes" << std::endl;
    goto done_free;
  }
  pos = len;
  if (len)
    pos--; // squash null termination
  strcpy(buf + pos, p);
  len = pos + strlen(p) + 1;
  RGW_LOG(0) << "RGWFormatter::write_data: len= " << len << " bytes" << std::endl;
done_free:
  if (!p_on_stack)
    free(p);
}

void RGWFormatter::flush()
{
  if (!buf)
    return;

  RGW_LOG(0) << "flush(): buf='" << buf << "'  strlen(buf)=" << strlen(buf) << std::endl;
  FCGX_PutStr(buf, len - 1, s->fcgx->out);
  free(buf);
  buf = NULL;
  len = 0;
  max_len = 0;
}
<commit_msg>rgw: fix buffer overflow<commit_after>#include <errno.h>

#include "rgw_common.h"
#include "rgw_acl.h"

#include "common/ceph_crypto.h"

using namespace ceph::crypto;

/* Loglevel of the gateway */
int rgw_log_level = 20;

int parse_time(const char *time_str, time_t *time)
{
  struct tm tm;
  memset(&tm, 0, sizeof(struct tm));
  if (!strptime(time_str, "%a, %d %b %Y %H:%M:%S %Z", &tm))
    return -EINVAL;

  *time = mktime(&tm);

  return 0;
}

/*
 * calculate the sha1 value of a given msg and key
 */
void calc_hmac_sha1(const char *key, int key_len,
                    const char *msg, int msg_len, char *dest)
/* destination should be CEPH_CRYPTO_HMACSHA1_DIGESTSIZE bytes long */
{
  HMACSHA1 hmac((const unsigned char *)key, key_len);
  hmac.Update((const unsigned char *)msg, msg_len);
  hmac.Final((unsigned char *)dest);

  char hex_str[(CEPH_CRYPTO_HMACSHA1_DIGESTSIZE * 2) + 1];
  buf_to_hex((unsigned char *)dest, CEPH_CRYPTO_HMACSHA1_DIGESTSIZE, hex_str);

  RGW_LOG(15) << "hmac=" << hex_str << endl;
}

int NameVal::parse()
{
  int delim_pos = str.find('=');
  int ret = 0;

  if (delim_pos < 0) {
    name = str;
    val = "";
    ret = 1;
  } else {
    name = str.substr(0, delim_pos);
    val = str.substr(delim_pos + 1);
  }

  RGW_LOG(10) << "parsed: name=" << name << " val=" << val << endl;
  return ret;
}

int XMLArgs::parse()
{
  int pos = 0, fpos;
  bool end = false;
  if (str[pos] == '?') pos++;

  while (!end) {
    fpos = str.find('&', pos);
    if (fpos  < pos) {
       end = true;
       fpos = str.size();
    }
    NameVal nv(str.substr(pos, fpos - pos));
    int ret = nv.parse();
    if (ret >= 0) {
      val_map[nv.get_name()] = nv.get_val();

      if (ret > 0) { /* this might be a sub-resource */
        if ((nv.get_name().compare("acl") == 0) ||
            (nv.get_name().compare("location") == 0) ||
            (nv.get_name().compare("torrent") == 0))
          sub_resource = nv.get_name();
      }
    }

    pos = fpos + 1;
  }

  return 0;
}

string& XMLArgs::get(string& name)
{
  map<string, string>::iterator iter;
  iter = val_map.find(name);
  if (iter == val_map.end())
    return empty_str;
  return iter->second;
}

string& XMLArgs::get(const char *name)
{
  string s(name);
  return get(s);
}

bool verify_permission(RGWAccessControlPolicy *policy, string& uid, int perm)
{
   if (!policy)
     return false;

   int acl_perm = policy->get_perm(uid, perm);

   return (perm == acl_perm);
}

bool verify_permission(struct req_state *s, int perm)
{
  return verify_permission(s->acl, s->user.user_id, perm);
}

static char hex_to_num(char c)
{
  static char table[256];
  static bool initialized = false;

  if (!initialized) {
    memset(table, -1, sizeof(table));
    int i;
    for (i = '0'; i<='9'; i++)
      table[i] = i - '0';
    for (i = 'A'; i<='F'; i++)
      table[i] = i - 'A' + 0xa;
    for (i = 'a'; i<='f'; i++)
      table[i] = i - 'a' + 0xa;
  }
  return table[(int)c];
}

bool url_decode(string& src_str, string& dest_str)
{
  RGW_LOG(10) << "in url_decode with " << src_str << endl;
  const char *src = src_str.c_str();
  char dest[src_str.size()];
  int pos = 0;
  char c;

  RGW_LOG(10) << "src=" << (void *)src << std::endl;

  while (*src) {
    if (*src != '%') {
      if (*src != '+') {
	dest[pos++] = *src++;
      } else {
	dest[pos++] = ' ';
	++src;
      }
    } else {
      src++;
      char c1 = hex_to_num(*src++);
      c = c1 << 4;
      if (c1 < 0)
        return false;
      c1 = hex_to_num(*src++);
      if (c1 < 0)
        return false;
      c |= c1;
      dest[pos++] = c;
    }
  }
  dest[pos] = 0;
  dest_str = dest;

  return true;
}

void RGWFormatter::write_data(const char *fmt, ...)
{
#define LARGE_ENOUGH_LEN 128
  int n, size = LARGE_ENOUGH_LEN;
  char s[size];
  char *p, *np;
  bool p_on_stack;
  va_list ap;
  int pos;

  p = s;
  p_on_stack = true;

  while (1) {
    va_start(ap, fmt);
    n = vsnprintf(p, size, fmt, ap);
    va_end(ap);

    if (n > -1 && n < size)
      goto done;
    /* Else try again with more space. */
    if (n > -1)    /* glibc 2.1 */
      size = n+1; /* precisely what is needed */
    else           /* glibc 2.0 */
      size *= 2;  /* twice the old size */
    if (p_on_stack)
      np = (char *)malloc(size);
    else
      np = (char *)realloc(p, size);
    if (!np)
      goto done_free;
    p = np;
    p_on_stack = false;
  }
done:
#define LARGE_ENOUGH_BUF 4096
  if (!buf) {
    max_len = max(LARGE_ENOUGH_BUF, size);
    buf = (char *)malloc(max_len);
  }

  if (len + size > max_len) {
    max_len = len + size + LARGE_ENOUGH_BUF;
    buf = (char *)realloc(buf, max_len);
  }
  if (!buf) {
    RGW_LOG(0) << "RGWFormatter::write_data: failed allocating " << max_len << " bytes" << std::endl;
    goto done_free;
  }
  pos = len;
  if (len)
    pos--; // squash null termination
  strcpy(buf + pos, p);
  len = pos + strlen(p) + 1;
  RGW_LOG(0) << "RGWFormatter::write_data: len= " << len << " bytes" << std::endl;
done_free:
  if (!p_on_stack)
    free(p);
}

void RGWFormatter::flush()
{
  if (!buf)
    return;

  RGW_LOG(0) << "flush(): buf='" << buf << "'  strlen(buf)=" << strlen(buf) << std::endl;
  FCGX_PutStr(buf, len - 1, s->fcgx->out);
  free(buf);
  buf = NULL;
  len = 0;
  max_len = 0;
}
<|endoftext|>