<commit_before>
#include <gmock/gmock.h>

#include <globjects/base/ref_ptr.h>

class ref_ptr_test : public testing::Test
{
public:
};

class ReferencedMock : public globjects::Referenced
{
public:
    MOCK_METHOD0(Die, void());
    virtual ~ReferencedMock() { Die(); }
};

TEST_F(ref_ptr_test, DeletesItsReferenced)
{
    // the ReferencedMock instance should be deleted on function exit

    globjects::ref_ptr<ReferencedMock> ref = new ReferencedMock;
    EXPECT_CALL(*ref, Die()).Times(1);
}

TEST_F(ref_ptr_test, SurvivesWhenReferenced)
{
    globjects::ref_ptr<ReferencedMock> owned;
    {
        globjects::ref_ptr<ReferencedMock> ref = new ReferencedMock;
        EXPECT_CALL(*ref, Die()).Times(1);
        owned = ref;
        EXPECT_EQ(owned->refCounter(), 2);
    }
    EXPECT_EQ(owned->refCounter(), 1);
}

TEST_F(ref_ptr_test, ReferencesSameInstanceWhenPassedOn)
{
    globjects::ref_ptr<ReferencedMock> ref = new ReferencedMock;
    EXPECT_CALL(*ref, Die()).Times(1);

    globjects::ref_ptr<ReferencedMock> a = ref;
    globjects::ref_ptr<ReferencedMock> b = ref;

    EXPECT_EQ(ref->refCounter(), 3);
    EXPECT_TRUE(a == b);
}

TEST_F(ref_ptr_test, ReferenceComparisonConstComparisonsCompile)
{
    return; // Just test compilation, not actual behavior

    ReferencedMock * t = new ReferencedMock;
    const ReferencedMock * const_t = new ReferencedMock;

    globjects::ref_ptr<ReferencedMock> ref_t = new ReferencedMock;
    const globjects::ref_ptr<ReferencedMock> const_ref_t = new ReferencedMock;
    globjects::ref_ptr<const ReferencedMock> ref_const_t = new ReferencedMock;
    const globjects::ref_ptr<const ReferencedMock> const_ref_const_t = new ReferencedMock;

    bool success1 = true;
    bool success2 = true;

    if (t == ref_t || t == const_ref_t || t == ref_const_t || t == const_ref_const_t)
        if (const_t == ref_t || const_t == const_ref_t || const_t == ref_const_t || const_t == const_ref_const_t)
            if (ref_t == const_ref_t || ref_t == ref_const_t || ref_t == const_ref_const_t)
                if (const_ref_t == ref_const_t || const_ref_t == const_ref_const_t)
                    if (ref_const_t == const_ref_const_t)
                    {
                        success1 = false;
                    }

    if (ref_t == t || const_ref_t == t || ref_const_t == t || const_ref_const_t == t)
        if (ref_t == const_t || const_ref_t == const_t || ref_const_t == const_t || const_ref_const_t == const_t)
            if (const_ref_t == ref_t || ref_const_t == ref_t || const_ref_const_t == ref_t)
                if (ref_const_t == const_ref_t || const_ref_const_t == const_ref_t)
                    if (const_ref_const_t == ref_const_t)
                    {
                        success2 = false;
                    }

    EXPECT_TRUE(success1 && success2);

    delete t;
    delete const_t;
}
<commit_msg>Fix CID #89085<commit_after>
#include <gmock/gmock.h>

#include <globjects/base/ref_ptr.h>

class ref_ptr_test : public testing::Test
{
public:
};

class ReferencedMock : public globjects::Referenced
{
public:
    MOCK_METHOD0(Die, void());
    virtual ~ReferencedMock() { Die(); }
};

TEST_F(ref_ptr_test, DeletesItsReferenced)
{
    // the ReferencedMock instance should be deleted on function exit

    globjects::ref_ptr<ReferencedMock> ref = new ReferencedMock;
    EXPECT_CALL(*ref, Die()).Times(1);
}

TEST_F(ref_ptr_test, SurvivesWhenReferenced)
{
    globjects::ref_ptr<ReferencedMock> owned;
    {
        globjects::ref_ptr<ReferencedMock> ref = new ReferencedMock;
        EXPECT_CALL(*ref, Die()).Times(1);
        owned = ref;
        EXPECT_EQ(owned->refCounter(), 2);
    }
    EXPECT_EQ(owned->refCounter(), 1);
}

TEST_F(ref_ptr_test, ReferencesSameInstanceWhenPassedOn)
{
    globjects::ref_ptr<ReferencedMock> ref = new ReferencedMock;
    EXPECT_CALL(*ref, Die()).Times(1);

    globjects::ref_ptr<ReferencedMock> a = ref;
    globjects::ref_ptr<ReferencedMock> b = ref;

    EXPECT_EQ(ref->refCounter(), 3);
    EXPECT_TRUE(a == b);
}

TEST_F(ref_ptr_test, ReferenceComparisonConstComparisonsCompile)
{
    SUCCEED(); // Just test compilation, not actual behavior

    ReferencedMock * t = new ReferencedMock;
    const ReferencedMock * const_t = new ReferencedMock;

    globjects::ref_ptr<ReferencedMock> ref_t = new ReferencedMock;
    const globjects::ref_ptr<ReferencedMock> const_ref_t = new ReferencedMock;
    globjects::ref_ptr<const ReferencedMock> ref_const_t = new ReferencedMock;
    const globjects::ref_ptr<const ReferencedMock> const_ref_const_t = new ReferencedMock;

    bool success1 = true;
    bool success2 = true;

    if (t == ref_t || t == const_ref_t || t == ref_const_t || t == const_ref_const_t)
        if (const_t == ref_t || const_t == const_ref_t || const_t == ref_const_t || const_t == const_ref_const_t)
            if (ref_t == const_ref_t || ref_t == ref_const_t || ref_t == const_ref_const_t)
                if (const_ref_t == ref_const_t || const_ref_t == const_ref_const_t)
                    if (ref_const_t == const_ref_const_t)
                    {
                        success1 = false;
                    }

    if (ref_t == t || const_ref_t == t || ref_const_t == t || const_ref_const_t == t)
        if (ref_t == const_t || const_ref_t == const_t || ref_const_t == const_t || const_ref_const_t == const_t)
            if (const_ref_t == ref_t || ref_const_t == ref_t || const_ref_const_t == ref_t)
                if (ref_const_t == const_ref_t || const_ref_const_t == const_ref_t)
                    if (const_ref_const_t == ref_const_t)
                    {
                        success2 = false;
                    }

    EXPECT_TRUE(success1 && success2);

    delete t;
    delete const_t;
}
<|endoftext|>


<commit_before>/*
 * FTGL - OpenGL font library
 *
 * Copyright (c) 2001-2004 Henry Maddocks <ftgl@opengl.geek.nz>
 *
 * 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.
 *
 * Alternatively, you can redistribute and/or modify this software under
 * the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License,
 * or (at your option) any later version.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
 */

#include "config.h"

#include <cassert>
#include <string> // For memset

#include "FTInternals.h"

#include "FTGLTextureFont.h"
#include "FTTextureGlyph.h"

inline GLuint NextPowerOf2( GLuint in)
{
     in -= 1;

     in |= in >> 16;
     in |= in >> 8;
     in |= in >> 4;
     in |= in >> 2;
     in |= in >> 1;

     return in + 1;
}

FTGLTextureFont::FTGLTextureFont( const char* fontFilePath)
:   FTFont( fontFilePath),
    maximumGLTextureSize(0),
    textureWidth(0),
    textureHeight(0),
    glyphHeight(0),
    glyphWidth(0),
    padding(3),
    xOffset(0),
    yOffset(0)
{
    remGlyphs = numGlyphs = face.GlyphCount();
}

FTGLTextureFont::FTGLTextureFont( const unsigned char *pBufferBytes, size_t bufferSizeInBytes)
:   FTFont( pBufferBytes, bufferSizeInBytes),
    maximumGLTextureSize(0),
    textureWidth(0),
    textureHeight(0),
    glyphHeight(0),
    glyphWidth(0),
    padding(3),
    xOffset(0),
    yOffset(0)
{
    remGlyphs = numGlyphs = face.GlyphCount();
}

FTGLTextureFont::~FTGLTextureFont()
{
    glDeleteTextures( textureIDList.size(), (const GLuint*)&textureIDList[0]);
}

FTGlyph* FTGLTextureFont::MakeGlyph( unsigned int glyphIndex)
{
    FT_GlyphSlot ftGlyph = face.Glyph( glyphIndex, FT_LOAD_NO_HINTING);

    if( ftGlyph)
    {
        glyphHeight = static_cast<int>( charSize.Height());
        glyphWidth = static_cast<int>( charSize.Width());

        if( textureIDList.empty())
        {
            textureIDList.push_back( CreateTexture());
            xOffset = yOffset = padding;
        }

        if( xOffset > ( textureWidth - glyphWidth))
        {
            xOffset = padding;
            yOffset += glyphHeight;

            if( yOffset > ( textureHeight - glyphHeight))
            {
                textureIDList.push_back( CreateTexture());
                yOffset = padding;
            }
        }

        FTTextureGlyph* tempGlyph = new FTTextureGlyph( ftGlyph, textureIDList[textureIDList.size() - 1],
                                                        xOffset, yOffset, textureWidth, textureHeight);
        xOffset += static_cast<int>( tempGlyph->BBox().upperX - tempGlyph->BBox().lowerX + padding);

        --remGlyphs;
        return tempGlyph;
    }

    err = face.Error();
    return NULL;
}

void FTGLTextureFont::CalculateTextureSize()
{
    if( !maximumGLTextureSize)
    {
        glGetIntegerv( GL_MAX_TEXTURE_SIZE, (GLint*)&maximumGLTextureSize);
        assert(maximumGLTextureSize); // If you hit this then you have an invalid OpenGL context.
    }

    textureWidth = NextPowerOf2( (remGlyphs * glyphWidth) + ( padding * 2));
    textureWidth = textureWidth > maximumGLTextureSize ? maximumGLTextureSize : textureWidth;

    int h = static_cast<int>( (textureWidth - ( padding * 2)) / glyphWidth);

    textureHeight = NextPowerOf2( (( numGlyphs / h) + 1) * glyphHeight);
    textureHeight = textureHeight > maximumGLTextureSize ? maximumGLTextureSize : textureHeight;
}

GLuint FTGLTextureFont::CreateTexture()
{
    CalculateTextureSize();

    int totalMemory = textureWidth * textureHeight;
    unsigned char* textureMemory = new unsigned char[totalMemory];
    memset( textureMemory, 0, totalMemory);

    GLuint textID;
    glGenTextures( 1, (GLuint*)&textID);

    glBindTexture( GL_TEXTURE_2D, textID);
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    glTexImage2D( GL_TEXTURE_2D, 0, GL_ALPHA, textureWidth, textureHeight, 0, GL_ALPHA, GL_UNSIGNED_BYTE, textureMemory);

    delete [] textureMemory;

    return textID;
}

bool FTGLTextureFont::FaceSize( const unsigned int size, const unsigned int res)
{
    if( !textureIDList.empty())
    {
        glDeleteTextures( textureIDList.size(), (const GLuint*)&textureIDList[0]);
        textureIDList.clear();
        remGlyphs = numGlyphs = face.GlyphCount();
    }

    return FTFont::FaceSize( size, res);
}

template <typename T>
inline void FTGLTextureFont::RenderI(const T* string)
{
    glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT);

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE

    FTTextureGlyph::ResetActiveTexture();

    FTFont::Render(string);

    glPopAttrib();
}

void FTGLTextureFont::Render(const char* string)
{
    RenderI(string);
}

void FTGLTextureFont::Render(const wchar_t* string)
{
    RenderI(string);
}

namespace C
{
    extern "C" FTGLfont* ftglCreateTextureFont(const char *fontname)
    {
        FTGLfont *ftgl = createFTFont(Texture, fontname);
        return ftgl;
    }
}

<commit_msg>  * Turn off the color buffer bit in the TextureFont renderer to increase     performance. Patch by Ton Roosendaal, from Blender commit r5362.<commit_after>/*
 * FTGL - OpenGL font library
 *
 * Copyright (c) 2001-2004 Henry Maddocks <ftgl@opengl.geek.nz>
 *
 * 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.
 *
 * Alternatively, you can redistribute and/or modify this software under
 * the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License,
 * or (at your option) any later version.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
 */

#include "config.h"

#include <cassert>
#include <string> // For memset

#include "FTInternals.h"

#include "FTGLTextureFont.h"
#include "FTTextureGlyph.h"

inline GLuint NextPowerOf2( GLuint in)
{
     in -= 1;

     in |= in >> 16;
     in |= in >> 8;
     in |= in >> 4;
     in |= in >> 2;
     in |= in >> 1;

     return in + 1;
}

FTGLTextureFont::FTGLTextureFont( const char* fontFilePath)
:   FTFont( fontFilePath),
    maximumGLTextureSize(0),
    textureWidth(0),
    textureHeight(0),
    glyphHeight(0),
    glyphWidth(0),
    padding(3),
    xOffset(0),
    yOffset(0)
{
    remGlyphs = numGlyphs = face.GlyphCount();
}

FTGLTextureFont::FTGLTextureFont( const unsigned char *pBufferBytes, size_t bufferSizeInBytes)
:   FTFont( pBufferBytes, bufferSizeInBytes),
    maximumGLTextureSize(0),
    textureWidth(0),
    textureHeight(0),
    glyphHeight(0),
    glyphWidth(0),
    padding(3),
    xOffset(0),
    yOffset(0)
{
    remGlyphs = numGlyphs = face.GlyphCount();
}

FTGLTextureFont::~FTGLTextureFont()
{
    glDeleteTextures( textureIDList.size(), (const GLuint*)&textureIDList[0]);
}

FTGlyph* FTGLTextureFont::MakeGlyph( unsigned int glyphIndex)
{
    FT_GlyphSlot ftGlyph = face.Glyph( glyphIndex, FT_LOAD_NO_HINTING);

    if( ftGlyph)
    {
        glyphHeight = static_cast<int>( charSize.Height());
        glyphWidth = static_cast<int>( charSize.Width());

        if( textureIDList.empty())
        {
            textureIDList.push_back( CreateTexture());
            xOffset = yOffset = padding;
        }

        if( xOffset > ( textureWidth - glyphWidth))
        {
            xOffset = padding;
            yOffset += glyphHeight;

            if( yOffset > ( textureHeight - glyphHeight))
            {
                textureIDList.push_back( CreateTexture());
                yOffset = padding;
            }
        }

        FTTextureGlyph* tempGlyph = new FTTextureGlyph( ftGlyph, textureIDList[textureIDList.size() - 1],
                                                        xOffset, yOffset, textureWidth, textureHeight);
        xOffset += static_cast<int>( tempGlyph->BBox().upperX - tempGlyph->BBox().lowerX + padding);

        --remGlyphs;
        return tempGlyph;
    }

    err = face.Error();
    return NULL;
}

void FTGLTextureFont::CalculateTextureSize()
{
    if( !maximumGLTextureSize)
    {
        glGetIntegerv( GL_MAX_TEXTURE_SIZE, (GLint*)&maximumGLTextureSize);
        assert(maximumGLTextureSize); // If you hit this then you have an invalid OpenGL context.
    }

    textureWidth = NextPowerOf2( (remGlyphs * glyphWidth) + ( padding * 2));
    textureWidth = textureWidth > maximumGLTextureSize ? maximumGLTextureSize : textureWidth;

    int h = static_cast<int>( (textureWidth - ( padding * 2)) / glyphWidth);

    textureHeight = NextPowerOf2( (( numGlyphs / h) + 1) * glyphHeight);
    textureHeight = textureHeight > maximumGLTextureSize ? maximumGLTextureSize : textureHeight;
}

GLuint FTGLTextureFont::CreateTexture()
{
    CalculateTextureSize();

    int totalMemory = textureWidth * textureHeight;
    unsigned char* textureMemory = new unsigned char[totalMemory];
    memset( textureMemory, 0, totalMemory);

    GLuint textID;
    glGenTextures( 1, (GLuint*)&textID);

    glBindTexture( GL_TEXTURE_2D, textID);
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    glTexImage2D( GL_TEXTURE_2D, 0, GL_ALPHA, textureWidth, textureHeight, 0, GL_ALPHA, GL_UNSIGNED_BYTE, textureMemory);

    delete [] textureMemory;

    return textID;
}

bool FTGLTextureFont::FaceSize( const unsigned int size, const unsigned int res)
{
    if( !textureIDList.empty())
    {
        glDeleteTextures( textureIDList.size(), (const GLuint*)&textureIDList[0]);
        textureIDList.clear();
        remGlyphs = numGlyphs = face.GlyphCount();
    }

    return FTFont::FaceSize( size, res);
}

template <typename T>
inline void FTGLTextureFont::RenderI(const T* string)
{
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE

    FTTextureGlyph::ResetActiveTexture();

    FTFont::Render(string);
}

void FTGLTextureFont::Render(const char* string)
{
    RenderI(string);
}

void FTGLTextureFont::Render(const wchar_t* string)
{
    RenderI(string);
}

namespace C
{
    extern "C" FTGLfont* ftglCreateTextureFont(const char *fontname)
    {
        FTGLfont *ftgl = createFTFont(Texture, fontname);
        return ftgl;
    }
}

<|endoftext|>


<commit_before>#include	"FTGLTextureFont.h"
#include	"FTGlyphContainer.h"
#include	"FTTextureGlyph.h"

using namespace std;

typedef unsigned long	UInt32; // a mac thing?

inline UInt32 NextPowerOf2( UInt32 in)
{
     in -= 1;

     in |= in >> 16;
     in |= in >> 8;
     in |= in >> 4;
     in |= in >> 2;
     in |= in >> 1;

     return in + 1;
}

FTGLTextureFont::FTGLTextureFont()
:	numTextures(1),
	textMem(0),
	padding(1),
	tempGlyph(0),
	maxTextSize(0),
	textureWidth(0),
	textureHeight(0),
	glyphHeight(0),
	glyphWidth(0)
{}

FTGLTextureFont::~FTGLTextureFont()
{
	glDeleteTextures( numTextures, (const GLuint*)glTextureID);
}

bool FTGLTextureFont::MakeGlyphList()
{
	if( !maxTextSize)
		glGetIntegerv( GL_MAX_TEXTURE_SIZE, (GLint*)&maxTextSize);

	glyphHeight = ( charSize.Height()) + padding;
	glyphWidth = ( charSize.Width()) + padding;

	GetSize();
	int totalMem;

	if( textureHeight > maxTextSize)
	{
		numTextures = static_cast<int>( textureHeight / maxTextSize) + 1;
		if( numTextures > 15) // FIXME
			numTextures = 15;

		int heightRemain = NextPowerOf2( textureHeight % maxTextSize);
		totalMem = ((maxTextSize * ( numTextures - 1)) + heightRemain) * textureWidth;

		glGenTextures( numTextures, (GLuint*)&glTextureID[0]);

		textMem = new unsigned char[totalMem]; // GL_ALPHA texture;
		memset( textMem, 0, totalMem);

		unsigned int glyphNum = 0;
		unsigned char* currTextPtr = textMem;

		for( int x = 0; x < numTextures - 1; ++x)
		{
			glyphNum = FillGlyphs( glyphNum, glTextureID[x], textureWidth, maxTextSize, currTextPtr);

			CreateTexture( x, textureWidth, maxTextSize, currTextPtr);

			currTextPtr += ( textureWidth * maxTextSize);
			++glyphNum;
		}

		glyphNum = FillGlyphs( glyphNum, glTextureID[numTextures - 1], textureWidth, heightRemain, currTextPtr);
		CreateTexture( numTextures - 1, textureWidth, heightRemain, currTextPtr);
	}
	else
	{
		textureHeight = NextPowerOf2( textureHeight);
		totalMem = textureWidth * textureHeight;

		glGenTextures( numTextures, (GLuint*)&glTextureID[0]);

		textMem = new unsigned char[totalMem]; // GL_ALPHA texture;
		memset( textMem, 0, totalMem);

		FillGlyphs( 0, glTextureID[0], textureWidth, textureHeight, textMem);
		CreateTexture( 0, textureWidth, textureHeight, textMem);
	}

	delete [] textMem;
	return !err;
}

unsigned int FTGLTextureFont::FillGlyphs( unsigned int glyphStart, int id, int width, int height, unsigned char* textdata)
{
	int currentTextX = padding;
	int currentTextY = padding;// + padding;

	float currTextU = (float)padding / (float)width;
	float currTextV = (float)padding / (float)height;

//	numGlyphs = 256; // FIXME hack
	unsigned int n;

	for( n = glyphStart; n <= numGlyphs; ++n)
	{
		FT_Glyph* ftGlyph = face.Glyph( n, FT_LOAD_NO_HINTING);

		if( ftGlyph)
		{
			unsigned char* data = textdata + (( currentTextY * width) + currentTextX);

			currTextU = (float)currentTextX / (float)width;

			tempGlyph = new FTTextureGlyph( *ftGlyph, id, data, width, height, currTextU, currTextV);
			glyphList->Add( tempGlyph);

			currentTextX += glyphWidth;
			if( currentTextX > ( width - glyphWidth))
			{
				currentTextY += glyphHeight;
				if( currentTextY > ( height - glyphHeight))
					return n;

				currentTextX = padding;
				currTextV = (float)currentTextY / (float)height;
			}
		}
		else
		{
			err = face.Error();
		}
	}

	return n;
}

void FTGLTextureFont::GetSize()
{
	//work out the max width. Most likely maxTextSize
	textureWidth = NextPowerOf2( numGlyphs * glyphWidth);
	if( textureWidth > maxTextSize)
	{
		textureWidth = maxTextSize;
	}

	int h = static_cast<int>( textureWidth / glyphWidth);
	textureHeight = (( numGlyphs / h) + 1) * glyphHeight;
}

void FTGLTextureFont::CreateTexture( int id, int width, int height, unsigned char* data)
{
	glPixelStorei( GL_UNPACK_ALIGNMENT, 1); //What does this do exactly?
	glBindTexture( GL_TEXTURE_2D, glTextureID[id]);
	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

	glTexImage2D( GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data);
}

void FTGLTextureFont::render( const char* string)
{
	glPushAttrib( GL_ENABLE_BIT | GL_HINT_BIT | GL_LINE_BIT | GL_PIXEL_MODE_BIT);

	glEnable(GL_BLEND);
 	glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE

	glBindTexture( GL_TEXTURE_2D, (GLuint)FTTextureGlyph::activeTextureID);

 	// QUADS are faster!? Less function call overhead?
 	glBegin( GL_QUADS);
 		FTFont::render( string);
 	glEnd();

	glPopAttrib();
}

void FTGLTextureFont::render( const wchar_t* string)
{
	glPushAttrib( GL_ENABLE_BIT | GL_HINT_BIT | GL_LINE_BIT | GL_PIXEL_MODE_BIT);

	glEnable(GL_BLEND);
 	glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE

	glBindTexture( GL_TEXTURE_2D, (GLuint)FTTextureGlyph::activeTextureID);

 	// QUADS are faster!? Less function call overhead?
 	glBegin( GL_QUADS);
 		FTFont::render( string);
 	glEnd();

	glPopAttrib();
}

<commit_msg>Enable texturing<commit_after>#include	"FTGLTextureFont.h"
#include	"FTGlyphContainer.h"
#include	"FTTextureGlyph.h"

using namespace std;

typedef unsigned long	UInt32; // a mac thing?

inline UInt32 NextPowerOf2( UInt32 in)
{
     in -= 1;

     in |= in >> 16;
     in |= in >> 8;
     in |= in >> 4;
     in |= in >> 2;
     in |= in >> 1;

     return in + 1;
}

FTGLTextureFont::FTGLTextureFont()
:	numTextures(1),
	textMem(0),
	padding(1),
	tempGlyph(0),
	maxTextSize(0),
	textureWidth(0),
	textureHeight(0),
	glyphHeight(0),
	glyphWidth(0)
{}

FTGLTextureFont::~FTGLTextureFont()
{
	glDeleteTextures( numTextures, (const GLuint*)glTextureID);
}

bool FTGLTextureFont::MakeGlyphList()
{
	glEnable( GL_TEXTURE_2D);

	if( !maxTextSize)
		glGetIntegerv( GL_MAX_TEXTURE_SIZE, (GLint*)&maxTextSize);

	glyphHeight = ( charSize.Height()) + padding;
	glyphWidth = ( charSize.Width()) + padding;

	GetSize();
	int totalMem;

	if( textureHeight > maxTextSize)
	{
		numTextures = static_cast<int>( textureHeight / maxTextSize) + 1;
		if( numTextures > 15) // FIXME
			numTextures = 15;

		int heightRemain = NextPowerOf2( textureHeight % maxTextSize);
		totalMem = ((maxTextSize * ( numTextures - 1)) + heightRemain) * textureWidth;

		glGenTextures( numTextures, (GLuint*)&glTextureID[0]);

		textMem = new unsigned char[totalMem]; // GL_ALPHA texture;
		memset( textMem, 0, totalMem);

		unsigned int glyphNum = 0;
		unsigned char* currTextPtr = textMem;

		for( int x = 0; x < numTextures - 1; ++x)
		{
			glyphNum = FillGlyphs( glyphNum, glTextureID[x], textureWidth, maxTextSize, currTextPtr);

			CreateTexture( x, textureWidth, maxTextSize, currTextPtr);

			currTextPtr += ( textureWidth * maxTextSize);
			++glyphNum;
		}

		glyphNum = FillGlyphs( glyphNum, glTextureID[numTextures - 1], textureWidth, heightRemain, currTextPtr);
		CreateTexture( numTextures - 1, textureWidth, heightRemain, currTextPtr);
	}
	else
	{
		textureHeight = NextPowerOf2( textureHeight);
		totalMem = textureWidth * textureHeight;

		glGenTextures( numTextures, (GLuint*)&glTextureID[0]);

		textMem = new unsigned char[totalMem]; // GL_ALPHA texture;
		memset( textMem, 0, totalMem);

		FillGlyphs( 0, glTextureID[0], textureWidth, textureHeight, textMem);
		CreateTexture( 0, textureWidth, textureHeight, textMem);
	}

	delete [] textMem;
	return !err;
}

unsigned int FTGLTextureFont::FillGlyphs( unsigned int glyphStart, int id, int width, int height, unsigned char* textdata)
{
	int currentTextX = padding;
	int currentTextY = padding;// + padding;

	float currTextU = (float)padding / (float)width;
	float currTextV = (float)padding / (float)height;

//	numGlyphs = 256; // FIXME hack
	unsigned int n;

	for( n = glyphStart; n <= numGlyphs; ++n)
	{
		FT_Glyph* ftGlyph = face.Glyph( n, FT_LOAD_NO_HINTING);

		if( ftGlyph)
		{
			unsigned char* data = textdata + (( currentTextY * width) + currentTextX);

			currTextU = (float)currentTextX / (float)width;

			tempGlyph = new FTTextureGlyph( *ftGlyph, id, data, width, height, currTextU, currTextV);
			glyphList->Add( tempGlyph);

			currentTextX += glyphWidth;
			if( currentTextX > ( width - glyphWidth))
			{
				currentTextY += glyphHeight;
				if( currentTextY > ( height - glyphHeight))
					return n;

				currentTextX = padding;
				currTextV = (float)currentTextY / (float)height;
			}
		}
		else
		{
			err = face.Error();
		}
	}

	return n;
}

void FTGLTextureFont::GetSize()
{
	//work out the max width. Most likely maxTextSize
	textureWidth = NextPowerOf2( numGlyphs * glyphWidth);
	if( textureWidth > maxTextSize)
	{
		textureWidth = maxTextSize;
	}

	int h = static_cast<int>( textureWidth / glyphWidth);
	textureHeight = (( numGlyphs / h) + 1) * glyphHeight;
}

void FTGLTextureFont::CreateTexture( int id, int width, int height, unsigned char* data)
{
	glPixelStorei( GL_UNPACK_ALIGNMENT, 1); //What does this do exactly?
	glBindTexture( GL_TEXTURE_2D, glTextureID[id]);
	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

	glTexImage2D( GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data);
}

void FTGLTextureFont::render( const char* string)
{
	glPushAttrib( GL_ENABLE_BIT | GL_HINT_BIT | GL_LINE_BIT | GL_PIXEL_MODE_BIT);

	glEnable(GL_BLEND);
 	glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE

	glBindTexture( GL_TEXTURE_2D, (GLuint)FTTextureGlyph::activeTextureID);

 	// QUADS are faster!? Less function call overhead?
 	glBegin( GL_QUADS);
 		FTFont::render( string);
 	glEnd();

	glPopAttrib();
}

void FTGLTextureFont::render( const wchar_t* string)
{
	glPushAttrib( GL_ENABLE_BIT | GL_HINT_BIT | GL_LINE_BIT | GL_PIXEL_MODE_BIT);

	glEnable(GL_BLEND);
 	glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE

	glBindTexture( GL_TEXTURE_2D, (GLuint)FTTextureGlyph::activeTextureID);

 	// QUADS are faster!? Less function call overhead?
 	glBegin( GL_QUADS);
 		FTFont::render( string);
 	glEnd();

	glPopAttrib();
}

<|endoftext|>


<commit_before>// =============================================================================
// PROJECT CHRONO - http://projectchrono.org
//
// Copyright (c) 2014 projectchrono.org
// All right reserved.
//
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file at the top level of the distribution and at
// http://projectchrono.org/license-chrono.txt.
//
// =============================================================================
// Authors: Radu Serban
// =============================================================================
//
// Base class for a sprocket template with gear profile composed of circular
// arcs and a flat seat, suitable for interaction with double-pin track shoes.
//
// =============================================================================

#include <cmath>

#include "chrono_vehicle/tracked_vehicle/sprocket/ChSprocketDoublePin.h"
#include "chrono_vehicle/tracked_vehicle/track_shoe/ChTrackShoeDoublePin.h"
#include "chrono_vehicle/tracked_vehicle/ChTrackAssembly.h"

namespace chrono {
namespace vehicle {

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
class SprocketDoublePinContactCB : public ChSystem::ChCustomComputeCollisionCallback {
  public:
    SprocketDoublePinContactCB(ChTrackAssembly* track,  ///< containing track assembly
                               double envelope,         ///< collision detection envelope
                               int gear_nteeth,         ///< number of teeth of the sprocket gear
                               double gear_RO,          ///< radius if the addendum circle
                               double gear_R,           ///< radius of the tooth arc profile
                               double gear_C,           ///< height of profile arcs
                               double gear_W,           ///< offset of profile arcs
                               double separation,       ///< separation between sprocket gears
                               double shoe_len,         ///< length of track shoe connector
                               double shoe_R            ///< radius of track shoe connector
                               )
        : m_track(track),
          m_envelope(envelope),
          m_sprocket(m_track->GetSprocket()),
          m_gear_nteeth(gear_nteeth),
          m_gear_RO(gear_RO),
          m_gear_R(gear_R),
          m_gear_C(gear_C),
          m_gear_W(gear_W),
          m_gear_Rhat(gear_R - envelope),
          m_separation(separation),
          m_shoe_len(shoe_len),
          m_shoe_R(shoe_R),
          m_shoe_Rhat(shoe_R + envelope) {}

    virtual void PerformCustomCollision(ChSystem* system) override;

  private:
    ChTrackAssembly* m_track;                // pointer to containing track assembly
    std::shared_ptr<ChSprocket> m_sprocket;  // handle to the sprocket

    double m_envelope;  // collision detection envelope

    int m_gear_nteeth;    // sprocket gear, number of teeth
    double m_gear_RO;     // sprocket gear, outer radius (radius of addendum circle)
    double m_gear_R;      // sprocket gear, arc radius
    double m_gear_C;      // sprocket gear, arc center height
    double m_gear_W;      // sprocket gear, arc center offset
    double m_separation;  // separation distance between sprocket gears
    double m_shoe_len;    // length of track shoe connector
    double m_shoe_R;      // radius of track shoe connector

    double m_gear_Rhat;  // adjusted gear arc radius
    double m_shoe_Rhat;  // adjusted she cylinder radius
};

void SprocketDoublePinContactCB::PerformCustomCollision(ChSystem* system) {
    // Return now if collision disabled on sproket or track shoes.
    if (!m_sprocket->GetGearBody()->GetCollide() || !m_track->GetTrackShoe(0)->GetShoeBody()->GetCollide())
        return;

    //// TODO
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
ChSprocketDoublePin::ChSprocketDoublePin(const std::string& name) : ChSprocket(name) {
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
ChSystem::ChCustomComputeCollisionCallback* ChSprocketDoublePin::GetCollisionCallback(ChTrackAssembly* track) {
    // Check compatibility between this type of sprocket and the track shoes.
    // We expect track shoes of type ChSinglePinShoe.
    auto shoe = std::dynamic_pointer_cast<ChTrackShoeDoublePin>(track->GetTrackShoe(0));
    assert(shoe);

    // Extract parameterization of gear profile
    int gear_nteeth = GetNumTeeth();
    double gear_RO = GetOuterRadius();
    double gear_R = GetArcRadius();
    double gear_C = GetArcCenterHeight();
    double gear_W = GetArcCenterOffset();

    // Extract parameterization of the shoe contact geometry.
    double shoe_len = shoe->GetConnectorLength();
    double shoe_R = shoe->GetConnectorRadius();

    // Create and return the callback object. Note: this pointer will be freed by the base class.
    return new SprocketDoublePinContactCB(track, 0.005, gear_nteeth, gear_RO, gear_R, gear_C, gear_W, GetSeparation(),
                                          shoe_len, shoe_R);
}

// -----------------------------------------------------------------------------
// Create and return the sprocket gear profile.
// -----------------------------------------------------------------------------
std::shared_ptr<geometry::ChLinePath> ChSprocketDoublePin::GetProfile() {
    auto profile = std::make_shared<geometry::ChLinePath>();

    int num_teeth = GetNumTeeth();
    double R_T = GetOuterRadius();
    double C = GetArcCenterHeight();
    double W = GetArcCenterOffset();
    double R_C = std::sqrt(C * C + W * W);
    double R = GetArcRadius();
    double D = W - R;

    double beta = CH_C_2PI / num_teeth;
    double sbeta = std::sin(beta / 2);
    double cbeta = std::cos(beta / 2);

    for (int i = 0; i < num_teeth; ++i) {
        ChVector<> p0L(-(R_T - D) * sbeta, (R_T - D) * cbeta, 0);
        ChVector<> p0R(+(R_T - D) * sbeta, (R_T - D) * cbeta, 0);

        ChVector<> p1L = p0L + ChVector<>(+D * cbeta, D * sbeta, 0);
        ChVector<> p1R = p0R + ChVector<>(-D * cbeta, D * sbeta, 0);

        ChVector<> p2L = ChVector<>(-C*sbeta, C*cbeta, 0) + ChVector<>(+D * cbeta, D * sbeta, 0);
        ChVector<> p2R = ChVector<>(+C*sbeta, C*cbeta, 0) + ChVector<>(-D * cbeta, D * sbeta, 0);

        ChVector<> p3L = p2L + ChVector<>(+R * cbeta, R * sbeta, 0);
        ChVector<> p3R = p2R + ChVector<>(-R * cbeta, R * sbeta, 0);

        ChVector<> p4L = p3L - ChVector<>(0, R, 0);
        ChVector<> p4R = p3R - ChVector<>(0, R, 0);

        double alpha = -i * beta;
        ChMatrix33<> rot(alpha, ChVector<>(0, 0, 1));

        p0L = rot * p0L;
        p1L = rot * p1L;
        p2L = rot * p2L;
        p3L = rot * p3L;
        p4L = rot * p4L;

        p0R = rot * p0R;
        p1R = rot * p1R;
        p2R = rot * p2R;
        p3R = rot * p3R;
        p4R = rot * p4R;

        geometry::ChLineArc arc1(ChCoordsys<>(p0L), D, alpha + CH_C_PI_2 + beta / 2, alpha + beta / 2);
        geometry::ChLineSegment seg2(p1L, p2L);
        geometry::ChLineArc arc3(ChCoordsys<>(p3L), R, alpha + CH_C_PI + beta / 2, alpha + 1.5 * CH_C_PI, true);
        geometry::ChLineSegment seg4(p4L, p4R);
        geometry::ChLineArc arc5(ChCoordsys<>(p3R), R, alpha + 1.5 * CH_C_PI, alpha + CH_C_2PI - beta / 2, true);
        geometry::ChLineSegment seg6(p2R, p1R);
        geometry::ChLineArc arc7(ChCoordsys<>(p0R), D, alpha + CH_C_PI - beta / 2, alpha + CH_C_PI_2 - beta / 2);

        profile->AddSubLine(arc1);
        profile->AddSubLine(seg2);
        profile->AddSubLine(arc3);
        profile->AddSubLine(seg4);
        profile->AddSubLine(arc5);
        profile->AddSubLine(seg6);
        profile->AddSubLine(arc7);
    }

    return profile;
}

}  // end namespace vehicle
}  // end namespace chrono
<commit_msg>Partial implementation of custom contact callback for double-pin sprocket-shoe contact (WIP)<commit_after>// =============================================================================
// PROJECT CHRONO - http://projectchrono.org
//
// Copyright (c) 2014 projectchrono.org
// All right reserved.
//
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file at the top level of the distribution and at
// http://projectchrono.org/license-chrono.txt.
//
// =============================================================================
// Authors: Radu Serban
// =============================================================================
//
// Base class for a sprocket template with gear profile composed of circular
// arcs and a flat seat, suitable for interaction with double-pin track shoes.
//
// =============================================================================

#include <cmath>

#include "chrono_vehicle/tracked_vehicle/sprocket/ChSprocketDoublePin.h"
#include "chrono_vehicle/tracked_vehicle/track_shoe/ChTrackShoeDoublePin.h"
#include "chrono_vehicle/tracked_vehicle/ChTrackAssembly.h"

namespace chrono {
namespace vehicle {

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
class SprocketDoublePinContactCB : public ChSystem::ChCustomComputeCollisionCallback {
  public:
    SprocketDoublePinContactCB(ChTrackAssembly* track,  ///< containing track assembly
                               double envelope,         ///< collision detection envelope
                               int gear_nteeth,         ///< number of teeth of the sprocket gear
                               double gear_RT,          ///< radius if the addendum circle
                               double gear_R,           ///< radius of the tooth arc profile
                               double gear_C,           ///< height of profile arcs
                               double gear_W,           ///< offset of profile arcs
                               double separation,       ///< separation between sprocket gears
                               double shoe_len,         ///< length of track shoe connector
                               double shoe_R            ///< radius of track shoe connector
                               )
        : m_track(track),
          m_envelope(envelope),
          m_sprocket(m_track->GetSprocket()),
          m_gear_nteeth(gear_nteeth),
          m_gear_RT(gear_RT),
          m_gear_R(gear_R),
          m_gear_C(gear_C),
          m_gear_W(gear_W),
          m_gear_Rhat(gear_R - envelope),
          m_separation(separation),
          m_shoe_len(shoe_len),
          m_shoe_R(shoe_R),
          m_shoe_Rhat(shoe_R + envelope) {
        m_R_sum = (m_shoe_len + 2 * m_shoe_R) + m_gear_RT;
        m_gear_RC = std::sqrt(m_gear_C * m_gear_C + m_gear_W * m_gear_W);
        m_gear_D = m_gear_W - m_gear_R;
        m_beta = CH_C_2PI / m_gear_nteeth;
        m_sbeta = std::sin(m_beta / 2);
        m_cbeta = std::cos(m_beta / 2);

    }

    virtual void PerformCustomCollision(ChSystem* system) override;

  private:
    // Test collision between a connector body and the sprocket's gear profiles.
    void CheckConnectorSprocket(std::shared_ptr<ChBody> connector,  // connector body
                                const ChVector<>& locS_abs          // center of sprocket (global frame)
                                );

    // Test collision between a circle and the gear profile (in the plane of the gear).
    void CheckCircleProfile(std::shared_ptr<ChBody> connector,  // connector body
                            const ChVector<>& loc,              // center of circular connector end
                            const ChVector<>& p1L,
                            const ChVector<>& p2L,
                            const ChVector<>& p3L,
                            const ChVector<>& p1R,
                            const ChVector<>& p2R,
                            const ChVector<>& p3R);

    ChTrackAssembly* m_track;                // pointer to containing track assembly
    std::shared_ptr<ChSprocket> m_sprocket;  // handle to the sprocket

    double m_envelope;  // collision detection envelope

    int m_gear_nteeth;    // sprocket gear, number of teeth
    double m_gear_RT;     // sprocket gear, outer tooth radius (radius of addendum circle)
    double m_gear_R;      // sprocket gear, arc radius
    double m_gear_C;      // sprocket gear, arc center height
    double m_gear_W;      // sprocket gear, arc center offset
    double m_separation;  // separation distance between sprocket gears

    double m_gear_D;   // tooth width (D = W - R)
    double m_gear_RC;  // radius of arc centers circle (RC^2 = C^2 + W^2)

    double m_beta;   // angle between two consecutive gear teeth
    double m_sbeta;  // sin(beta/2)
    double m_cbeta;  // cos(beta/2)

    double m_shoe_len;  // length of track shoe connector
    double m_shoe_R;    // radius of track shoe connector

    double m_gear_Rhat;  // adjusted gear arc radius
    double m_shoe_Rhat;  // adjusted shoe cylinder radius

    double m_R_sum;  // test quantity for broadphase check
};

// Add contacts between the sprocket and track shoes.
void SprocketDoublePinContactCB::PerformCustomCollision(ChSystem* system) {
    // Return now if collision disabled on sproket.
    if (!m_sprocket->GetGearBody()->GetCollide())
        return;

    // Sprocket gear center location (expressed in global frame)
    ChVector<> locS_abs = m_sprocket->GetGearBody()->GetPos();

    // Loop over all track shoes in the associated track
    for (size_t is = 0; is < m_track->GetNumTrackShoes(); ++is) {
        auto shoe = std::static_pointer_cast<ChTrackShoeDoublePin>(m_track->GetTrackShoe(is));

        // Perform collision test for the "left" connector body
        CheckConnectorSprocket(shoe->m_connector_L, locS_abs);

        // Perform collision test for the "right" connector body
        CheckConnectorSprocket(shoe->m_connector_R, locS_abs);
    }
}

// Perform collision test between the specified connector body and the associated sprocket.
void SprocketDoublePinContactCB::CheckConnectorSprocket(std::shared_ptr<ChBody> connector, const ChVector<>& locS_abs) {
    // (1) Express the center of the connector body in the sprocket frame
    ChVector<> loc = m_sprocket->GetGearBody()->TransformPointParentToLocal(connector->GetPos());

    // (2) Broadphase collision test: no contact if the connector's center is too far from the
    // center of the gear (test perfomed in the sprocket's x-z plane).
    if (loc.x * loc.x + loc.z * loc.z > m_R_sum * m_R_sum)
        return;

    // (3) Working in the frame of the sprocket, find the candidate tooth space.
    // This is the closest tooth space to the connector center point.

    // Angle formed by 'locC' and the line z>0
    double angle = std::atan2(loc.x, loc.z);
    // Find angle of closest tooth space
    double alpha = m_beta * std::round(angle / m_beta);
    // Convert to degrees
    double alpha_deg = alpha * 180 / CH_C_PI;

    // (4) Calculate the points that define the current tooth space.
    // Note that all these points will have Y = locC.y
    ChVector<> p0L(-(m_gear_RT - m_gear_D) * m_sbeta, loc.y, (m_gear_RT - m_gear_D) * m_cbeta);
    ChVector<> p0R(+(m_gear_RT - m_gear_D) * m_sbeta, loc.y, (m_gear_RT - m_gear_D) * m_cbeta);

    ChVector<> p1L = p0L + ChVector<>(+m_gear_D * m_cbeta, 0, m_gear_D * m_sbeta);
    ChVector<> p1R = p0R + ChVector<>(-m_gear_D * m_cbeta, 0, m_gear_D * m_sbeta);

    ChVector<> p2L = ChVector<>(-m_gear_C * m_sbeta, loc.y, m_gear_C * m_cbeta) +
                     ChVector<>(+m_gear_D * m_cbeta, 0, m_gear_D * m_sbeta);
    ChVector<> p2R = ChVector<>(+m_gear_C * m_sbeta, loc.y, m_gear_C * m_cbeta) +
                     ChVector<>(-m_gear_D * m_cbeta, 0, m_gear_D * m_sbeta);

    ChVector<> p3L = p2L + ChVector<>(+m_gear_R * m_cbeta, 0, m_gear_R * m_sbeta);
    ChVector<> p3R = p2R + ChVector<>(-m_gear_R * m_cbeta, 0, m_gear_R * m_sbeta);

    ChVector<> p4L = p3L - ChVector<>(0, 0, m_gear_R);
    ChVector<> p4R = p3R - ChVector<>(0, 0, m_gear_R);

    ChMatrix33<> rot(alpha, ChVector<>(0, 1, 0));

    p0L = rot * p0L;
    p1L = rot * p1L;
    p2L = rot * p2L;
    p3L = rot * p3L;
    p4L = rot * p4L;

    p0R = rot * p0R;
    p1R = rot * p1R;
    p2R = rot * p2R;
    p3R = rot * p3R;
    p4R = rot * p4R;

    // (5) Express the centers of the two connector end-caps in the sprocket frame.
    ChVector<> P1_abs = connector->TransformPointLocalToParent(ChVector<>(m_shoe_len / 2, 0, 0));
    ChVector<> P2_abs = connector->TransformPointLocalToParent(ChVector<>(-m_shoe_len / 2, 0, 0));
    ChVector<> P1 = m_sprocket->GetGearBody()->TransformPointParentToLocal(P1_abs);
    ChVector<> P2 = m_sprocket->GetGearBody()->TransformPointParentToLocal(P2_abs);

    ////if (loc.y > 0) {
    ////    std::cout << loc.x << " " << loc.y << " " << loc.z << std::endl;
    ////    std::cout << P1.x << " " << P1.y << " " << P1.z << std::endl;
    ////    std::cout << P2.x << " " << P2.y << " " << P2.z << std::endl;
    ////    std::cout << p0L.x << " " << p0L.y << " " << p0L.z << std::endl;
    ////    std::cout << p1L.x << " " << p1L.y << " " << p1L.z << std::endl;
    ////    std::cout << p2L.x << " " << p2L.y << " " << p2L.z << std::endl;
    ////    std::cout << p3L.x << " " << p3L.y << " " << p3L.z << std::endl;
    ////    std::cout << p4L.x << " " << p4L.y << " " << p4L.z << std::endl;
    ////    std::cout << p0R.x << " " << p0R.y << " " << p0R.z << std::endl;
    ////    std::cout << p1R.x << " " << p1R.y << " " << p1R.z << std::endl;
    ////    std::cout << p2R.x << " " << p2R.y << " " << p2R.z << std::endl;
    ////    std::cout << p3R.x << " " << p3R.y << " " << p3R.z << std::endl;
    ////    std::cout << p4R.x << " " << p4R.y << " " << p4R.z << std::endl;
    ////    std::cout << std::endl;
    ////}

    // (6) Perform collision test between the front end of the connector and the gear profile.
    CheckCircleProfile(connector, P1, p1L, p2L, p3L, p1R, p2R, p3R);

    // (7) Perform collision test between the rear end of the connector and the gear profile.
    CheckCircleProfile(connector, P2, p1L, p2L, p3L, p1R, p2R, p3R);
}

// Working in the (x-z) plane of the gear, perform a 2D collision test between a circle
// of radius m_shoe_R centered at the specified location and the gear profile.
void SprocketDoublePinContactCB::CheckCircleProfile(std::shared_ptr<ChBody> connector,
                                                    const ChVector<>& loc,
                                                    const ChVector<>& p1L,
                                                    const ChVector<>& p2L,
                                                    const ChVector<>& p3L,
                                                    const ChVector<>& p1R,
                                                    const ChVector<>& p2R,
                                                    const ChVector<>& p3R) {
    // Check circle against arc centered at p3L.

    // Check circle against arc centered at p3R.

    // Check circle against segment p1L - p2L.

    // Check circle against segment p1R - p2R.

}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
ChSprocketDoublePin::ChSprocketDoublePin(const std::string& name) : ChSprocket(name) {
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
ChSystem::ChCustomComputeCollisionCallback* ChSprocketDoublePin::GetCollisionCallback(ChTrackAssembly* track) {
    // Check compatibility between this type of sprocket and the track shoes.
    // We expect track shoes of type ChSinglePinShoe.
    auto shoe = std::dynamic_pointer_cast<ChTrackShoeDoublePin>(track->GetTrackShoe(0));
    assert(shoe);

    // Extract parameterization of gear profile
    int gear_nteeth = GetNumTeeth();
    double gear_RT = GetOuterRadius();
    double gear_R = GetArcRadius();
    double gear_C = GetArcCenterHeight();
    double gear_W = GetArcCenterOffset();

    // Extract parameterization of the shoe connector contact geometry.
    double shoe_len = shoe->GetConnectorLength();
    double shoe_R = shoe->GetConnectorRadius();

    // Create and return the callback object. Note: this pointer will be freed by the base class.
    return new SprocketDoublePinContactCB(track, 0.005, gear_nteeth, gear_RT, gear_R, gear_C, gear_W, GetSeparation(),
                                          shoe_len, shoe_R);
}

// -----------------------------------------------------------------------------
// Create and return the sprocket gear profile.
// -----------------------------------------------------------------------------
std::shared_ptr<geometry::ChLinePath> ChSprocketDoublePin::GetProfile() {
    auto profile = std::make_shared<geometry::ChLinePath>();

    int num_teeth = GetNumTeeth();
    double R_T = GetOuterRadius();
    double C = GetArcCenterHeight();
    double W = GetArcCenterOffset();
    double R_C = std::sqrt(C * C + W * W);
    double R = GetArcRadius();
    double D = W - R;

    double beta = CH_C_2PI / num_teeth;
    double sbeta = std::sin(beta / 2);
    double cbeta = std::cos(beta / 2);

    for (int i = 0; i < num_teeth; ++i) {
        ChVector<> p0L(-(R_T - D) * sbeta, (R_T - D) * cbeta, 0);
        ChVector<> p0R(+(R_T - D) * sbeta, (R_T - D) * cbeta, 0);

        ChVector<> p1L = p0L + ChVector<>(+D * cbeta, D * sbeta, 0);
        ChVector<> p1R = p0R + ChVector<>(-D * cbeta, D * sbeta, 0);

        ChVector<> p2L = ChVector<>(-C*sbeta, C*cbeta, 0) + ChVector<>(+D * cbeta, D * sbeta, 0);
        ChVector<> p2R = ChVector<>(+C*sbeta, C*cbeta, 0) + ChVector<>(-D * cbeta, D * sbeta, 0);

        ChVector<> p3L = p2L + ChVector<>(+R * cbeta, R * sbeta, 0);
        ChVector<> p3R = p2R + ChVector<>(-R * cbeta, R * sbeta, 0);

        ChVector<> p4L = p3L - ChVector<>(0, R, 0);
        ChVector<> p4R = p3R - ChVector<>(0, R, 0);

        double alpha = -i * beta;
        ChMatrix33<> rot(alpha, ChVector<>(0, 0, 1));

        p0L = rot * p0L;
        p1L = rot * p1L;
        p2L = rot * p2L;
        p3L = rot * p3L;
        p4L = rot * p4L;

        p0R = rot * p0R;
        p1R = rot * p1R;
        p2R = rot * p2R;
        p3R = rot * p3R;
        p4R = rot * p4R;

        geometry::ChLineArc arc1(ChCoordsys<>(p0L), D, alpha + CH_C_PI_2 + beta / 2, alpha + beta / 2);
        geometry::ChLineSegment seg2(p1L, p2L);
        geometry::ChLineArc arc3(ChCoordsys<>(p3L), R, alpha + CH_C_PI + beta / 2, alpha + 1.5 * CH_C_PI, true);
        geometry::ChLineSegment seg4(p4L, p4R);
        geometry::ChLineArc arc5(ChCoordsys<>(p3R), R, alpha + 1.5 * CH_C_PI, alpha + CH_C_2PI - beta / 2, true);
        geometry::ChLineSegment seg6(p2R, p1R);
        geometry::ChLineArc arc7(ChCoordsys<>(p0R), D, alpha + CH_C_PI - beta / 2, alpha + CH_C_PI_2 - beta / 2);

        profile->AddSubLine(arc1);
        profile->AddSubLine(seg2);
        profile->AddSubLine(arc3);
        profile->AddSubLine(seg4);
        profile->AddSubLine(arc5);
        profile->AddSubLine(seg6);
        profile->AddSubLine(arc7);
    }

    return profile;
}

}  // end namespace vehicle
}  // end namespace chrono
<|endoftext|>


<commit_before>#include <Poco/Exception.h>

#include "di/Injectable.h"
#include "model/ModuleType.h"
#include "provider/DeviceInfoProvider.h"
#include "util/DevicesSAXHandler.h"

using namespace std;
using namespace Poco;
using namespace Poco::XML;
using namespace BeeeOn;

BEEEON_OBJECT_BEGIN(BeeeOn, DeviceInfoProvider)
BEEEON_OBJECT_CASTABLE(InfoProvider<DeviceInfo>)
BEEEON_OBJECT_PROPERTY("devicesFile", &DeviceInfoProvider::setDevicesFile)
BEEEON_OBJECT_PROPERTY("typeInfoProvider", &DeviceInfoProvider::setTypeInfoProvider)
BEEEON_OBJECT_PROPERTY("subtypeInfoProvider", &DeviceInfoProvider::setSubtypeInfoProvider)
BEEEON_OBJECT_HOOK("done", &DeviceInfoProvider::loadInfo)
BEEEON_OBJECT_END(BeeeOn, DeviceInfoProvider)

DeviceInfoProvider::DeviceInfoProvider():
	m_typeProvider(&NullInfoProvider<TypeInfo>::instance()),
	m_subtypeProvider(&NullInfoProvider<SubtypeInfo>::instance())
{
}

void DeviceInfoProvider::setDevicesFile(const std::string &devicesFile)
{
	m_devicesFile = devicesFile;
}

void DeviceInfoProvider::setTypeInfoProvider(InfoProvider<TypeInfo> *provider)
{
	m_typeProvider = provider == NULL?
		&NullInfoProvider<TypeInfo>::instance() : provider;
}

void DeviceInfoProvider::setSubtypeInfoProvider(InfoProvider<SubtypeInfo> *provider)
{
	m_subtypeProvider = provider == NULL?
		&NullInfoProvider<SubtypeInfo>::instance() : provider;
}

DeviceInfo DeviceInfoProvider::resolveTypes(const DeviceInfo &device)
{
	static const TypeInfoID TYPE_ENUM_ID = ModuleType::Type::TYPE_ENUM;

	DeviceInfo result(device);
	result.clear();

	for (auto &module : device) {
		const TypeInfoID &id = module.type()->id();
		const SharedPtr<TypeInfo> info = m_typeProvider->findById(id);

		if (info.isNull()) {
			throw IllegalStateException(
				"could not resolve type " + id.toString()
				+ " for device " + device);
		}

		ModuleInfo copy(module);
		copy.setType(info);

		if (id == TYPE_ENUM_ID) {
			if (module.subtype().isNull()) {
				throw IllegalStateException(
					"missing subtype for enum for device " + device);
			}

			const SubtypeInfoID &id = module.subtype()->id();
			const SharedPtr<SubtypeInfo> subtypeInfo = m_subtypeProvider->findById(id);

			if (subtypeInfo.isNull()) {
				throw IllegalStateException(
					"no such subtype " + id.toString() + " for device " + device);
			}

			copy.setSubtype(subtypeInfo);
		}

		result.add(copy);
	}

	return result;
}

void DeviceInfoProvider::loadInfo()
{
	parseFile<DevicesSAXHandler>(m_devicesFile, "device");

	InfoProvider<DeviceInfo>::InfoSet set;

	for (auto &device : infoSet())
		set.insert(new DeviceInfo(resolveTypes(*device)));

	infoSet() = set;
}

const SharedPtr<DeviceInfo> DeviceInfoProvider::findByNameAndVendor(
		const std::string &name, const std::string &vendor) const
{
	for (auto info : infoSet()) {
		if (info->match(name, vendor))
			return info;
	}

	return NULL;
}
<commit_msg>DeviceInfoProvider: handle subtype for TYPE_BITMAP as well<commit_after>#include <Poco/Exception.h>

#include "di/Injectable.h"
#include "model/ModuleType.h"
#include "provider/DeviceInfoProvider.h"
#include "util/DevicesSAXHandler.h"

using namespace std;
using namespace Poco;
using namespace Poco::XML;
using namespace BeeeOn;

BEEEON_OBJECT_BEGIN(BeeeOn, DeviceInfoProvider)
BEEEON_OBJECT_CASTABLE(InfoProvider<DeviceInfo>)
BEEEON_OBJECT_PROPERTY("devicesFile", &DeviceInfoProvider::setDevicesFile)
BEEEON_OBJECT_PROPERTY("typeInfoProvider", &DeviceInfoProvider::setTypeInfoProvider)
BEEEON_OBJECT_PROPERTY("subtypeInfoProvider", &DeviceInfoProvider::setSubtypeInfoProvider)
BEEEON_OBJECT_HOOK("done", &DeviceInfoProvider::loadInfo)
BEEEON_OBJECT_END(BeeeOn, DeviceInfoProvider)

DeviceInfoProvider::DeviceInfoProvider():
	m_typeProvider(&NullInfoProvider<TypeInfo>::instance()),
	m_subtypeProvider(&NullInfoProvider<SubtypeInfo>::instance())
{
}

void DeviceInfoProvider::setDevicesFile(const std::string &devicesFile)
{
	m_devicesFile = devicesFile;
}

void DeviceInfoProvider::setTypeInfoProvider(InfoProvider<TypeInfo> *provider)
{
	m_typeProvider = provider == NULL?
		&NullInfoProvider<TypeInfo>::instance() : provider;
}

void DeviceInfoProvider::setSubtypeInfoProvider(InfoProvider<SubtypeInfo> *provider)
{
	m_subtypeProvider = provider == NULL?
		&NullInfoProvider<SubtypeInfo>::instance() : provider;
}

DeviceInfo DeviceInfoProvider::resolveTypes(const DeviceInfo &device)
{
	static const TypeInfoID TYPE_ENUM_ID = ModuleType::Type::TYPE_ENUM;
	static const TypeInfoID TYPE_BITMAP_ID = ModuleType::Type::TYPE_BITMAP;

	DeviceInfo result(device);
	result.clear();

	for (auto &module : device) {
		const TypeInfoID &id = module.type()->id();
		const SharedPtr<TypeInfo> info = m_typeProvider->findById(id);

		if (info.isNull()) {
			throw IllegalStateException(
				"could not resolve type " + id.toString()
				+ " for device " + device);
		}

		ModuleInfo copy(module);
		copy.setType(info);

		if (id == TYPE_ENUM_ID || id == TYPE_BITMAP_ID) {
			if (module.subtype().isNull()) {
				throw IllegalStateException(
					"missing subtype for enum for device " + device);
			}

			const SubtypeInfoID &id = module.subtype()->id();
			const SharedPtr<SubtypeInfo> subtypeInfo = m_subtypeProvider->findById(id);

			if (subtypeInfo.isNull()) {
				throw IllegalStateException(
					"no such subtype " + id.toString() + " for device " + device);
			}

			copy.setSubtype(subtypeInfo);
		}

		result.add(copy);
	}

	return result;
}

void DeviceInfoProvider::loadInfo()
{
	parseFile<DevicesSAXHandler>(m_devicesFile, "device");

	InfoProvider<DeviceInfo>::InfoSet set;

	for (auto &device : infoSet())
		set.insert(new DeviceInfo(resolveTypes(*device)));

	infoSet() = set;
}

const SharedPtr<DeviceInfo> DeviceInfoProvider::findByNameAndVendor(
		const std::string &name, const std::string &vendor) const
{
	for (auto info : infoSet()) {
		if (info->match(name, vendor))
			return info;
	}

	return NULL;
}
<|endoftext|>


<commit_before>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2013-2015 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. 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 OWNER 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.
 *
 *********************************************************************************/

#include <inviwo/qt/widgets/eventconverterqt.h>

#include <QMouseEvent>
#include <QWheelEvent>
#include <QInputEvent>
#include <QKeyEvent>
#ifndef QT_NO_GESTURES
#include <QGesture>
#endif

namespace inviwo {

EventConverterQt::EventConverterQt() {}
EventConverterQt::~EventConverterQt() {}

MouseEvent::MouseButton inviwo::EventConverterQt::getMouseButton(const QMouseEvent* e) {
    if (e->buttons() == Qt::LeftButton)
        return MouseEvent::MOUSE_BUTTON_LEFT;
    else if (e->buttons() == Qt::RightButton)
        return MouseEvent::MOUSE_BUTTON_RIGHT;
    else if (e->buttons() == Qt::MiddleButton)
        return MouseEvent::MOUSE_BUTTON_MIDDLE;

    return MouseEvent::MOUSE_BUTTON_NONE;
}

MouseEvent::MouseButton EventConverterQt::getMouseButtonCausingEvent(const QMouseEvent* e) {
	// QMouseEvent::getButtons does not
	// include the button that caused the event.
	// The QMouseEvent::getButton function
	// returns the button that caused the event
	if (e->button() == Qt::LeftButton)
		return MouseEvent::MOUSE_BUTTON_LEFT;
	else if (e->buttons() == Qt::RightButton)
		return MouseEvent::MOUSE_BUTTON_RIGHT;
	else if (e->buttons() == Qt::MiddleButton)
		return MouseEvent::MOUSE_BUTTON_MIDDLE;

	return MouseEvent::MOUSE_BUTTON_NONE;
}

MouseEvent::MouseButton inviwo::EventConverterQt::getMouseWheelButton(const QWheelEvent* e) {
    if (e->buttons() == Qt::LeftButton)
        return MouseEvent::MOUSE_BUTTON_LEFT;
    else if (e->buttons() == Qt::RightButton)
        return MouseEvent::MOUSE_BUTTON_RIGHT;
    else if (e->buttons() == Qt::MiddleButton)
        return MouseEvent::MOUSE_BUTTON_MIDDLE;

    return MouseEvent::MOUSE_BUTTON_NONE;
}

#ifndef QT_NO_GESTURES
GestureEvent::GestureState inviwo::EventConverterQt::getGestureState(const QGesture* gesture){
    if (gesture->state() == Qt::GestureStarted)
        return GestureEvent::GESTURE_STATE_STARTED;
    else if (gesture->state() == Qt::GestureUpdated)
        return GestureEvent::GESTURE_STATE_UPDATED;
    else if (gesture->state() == Qt::GestureFinished)
        return GestureEvent::GESTURE_STATE_ENDED;
    else if (gesture->state() == Qt::GestureCanceled)
        return GestureEvent::GESTURE_STATE_CANCELED;

    return GestureEvent::GESTURE_STATE_NONE;
}
#endif

InteractionEvent::Modifier inviwo::EventConverterQt::getModifier(const QInputEvent* e) {
    if (e->modifiers() == Qt::ShiftModifier)
        return InteractionEvent::MODIFIER_SHIFT;
    else if (e->modifiers() == Qt::ControlModifier)
        return InteractionEvent::MODIFIER_CTRL;
    else if (e->modifiers() == Qt::AltModifier)
        return InteractionEvent::MODIFIER_ALT;

    return InteractionEvent::MODIFIER_NONE;
}

int EventConverterQt::getKeyButton(const QKeyEvent* e) {
    return e->key();

// This does not work on OSX and makes no sense.
//    char key = toupper(e->nativeVirtualKey());
//
//    if ((key >= '0' && key <= '9')||(key >= 'A' && key <= 'Z'))
//        return key;
//    else
//        return 0;
}

} // namespace<commit_msg>Qt: Fixed release event button for all buttons.<commit_after>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2013-2015 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. 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 OWNER 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.
 *
 *********************************************************************************/

#include <inviwo/qt/widgets/eventconverterqt.h>

#include <QMouseEvent>
#include <QWheelEvent>
#include <QInputEvent>
#include <QKeyEvent>
#ifndef QT_NO_GESTURES
#include <QGesture>
#endif

namespace inviwo {

EventConverterQt::EventConverterQt() {}
EventConverterQt::~EventConverterQt() {}

MouseEvent::MouseButton inviwo::EventConverterQt::getMouseButton(const QMouseEvent* e) {
	switch (e->buttons())
	{
	case Qt::LeftButton:
		return MouseEvent::MOUSE_BUTTON_LEFT;
	case Qt::RightButton:
		return MouseEvent::MOUSE_BUTTON_RIGHT;
	case Qt::MiddleButton:
		return MouseEvent::MOUSE_BUTTON_MIDDLE;
	default:
		return MouseEvent::MOUSE_BUTTON_NONE;
	}
}

MouseEvent::MouseButton EventConverterQt::getMouseButtonCausingEvent(const QMouseEvent* e) {
	// QMouseEvent::getButtons does not
	// include the button that caused the event.
	// The QMouseEvent::getButton function
	// returns the button that caused the event
	switch (e->button())
	{
	case Qt::LeftButton:
		return MouseEvent::MOUSE_BUTTON_LEFT;
	case Qt::RightButton:
		return MouseEvent::MOUSE_BUTTON_RIGHT;
	case Qt::MiddleButton:
		return MouseEvent::MOUSE_BUTTON_MIDDLE;
	default:
		return MouseEvent::MOUSE_BUTTON_NONE;
	}
}

MouseEvent::MouseButton inviwo::EventConverterQt::getMouseWheelButton(const QWheelEvent* e) {
    if (e->buttons() == Qt::LeftButton)
        return MouseEvent::MOUSE_BUTTON_LEFT;
    else if (e->buttons() == Qt::RightButton)
        return MouseEvent::MOUSE_BUTTON_RIGHT;
    else if (e->buttons() == Qt::MiddleButton)
        return MouseEvent::MOUSE_BUTTON_MIDDLE;

    return MouseEvent::MOUSE_BUTTON_NONE;
}

#ifndef QT_NO_GESTURES
GestureEvent::GestureState inviwo::EventConverterQt::getGestureState(const QGesture* gesture){
    if (gesture->state() == Qt::GestureStarted)
        return GestureEvent::GESTURE_STATE_STARTED;
    else if (gesture->state() == Qt::GestureUpdated)
        return GestureEvent::GESTURE_STATE_UPDATED;
    else if (gesture->state() == Qt::GestureFinished)
        return GestureEvent::GESTURE_STATE_ENDED;
    else if (gesture->state() == Qt::GestureCanceled)
        return GestureEvent::GESTURE_STATE_CANCELED;

    return GestureEvent::GESTURE_STATE_NONE;
}
#endif

InteractionEvent::Modifier inviwo::EventConverterQt::getModifier(const QInputEvent* e) {
    if (e->modifiers() == Qt::ShiftModifier)
        return InteractionEvent::MODIFIER_SHIFT;
    else if (e->modifiers() == Qt::ControlModifier)
        return InteractionEvent::MODIFIER_CTRL;
    else if (e->modifiers() == Qt::AltModifier)
        return InteractionEvent::MODIFIER_ALT;

    return InteractionEvent::MODIFIER_NONE;
}

int EventConverterQt::getKeyButton(const QKeyEvent* e) {
    return e->key();

// This does not work on OSX and makes no sense.
//    char key = toupper(e->nativeVirtualKey());
//
//    if ((key >= '0' && key <= '9')||(key >= 'A' && key <= 'Z'))
//        return key;
//    else
//        return 0;
}

} // namespace<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/pm/p9_query_cache_access_state.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,2017                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file  p9_query_cache_access_state.C
/// @brief Check the stop level for the EX caches and sets boolean scomable parameters
///
// *HWP HWP Owner: Christina Graves <clgraves@us.ibm.com>
// *HWP Backup HWP Owner: Greg Still <stillgs@us.ibm.com>
// *HWP FW Owner:  Sangeetha T S <sangeet2@in.ibm.com>
// *HWP Team: PM
// *HWP Level: 2
// *HWP Consumed by: FSP:HS:SBE
///
///
///
/// @verbatim
/// High-level procedure flow:
///     - For the quad target, read the Stop State History register in the PPM
///       and use the actual stop level to determine if the quad has power and is being
///       clocked.
/// @endverbatim
///
//------------------------------------------------------------------------------

// ----------------------------------------------------------------------
// Includes
// ----------------------------------------------------------------------

#include <p9_quad_scom_addresses.H>
#include <p9_query_cache_access_state.H>

// ----------------------------------------------------------------------
// Constants
// ----------------------------------------------------------------------

const uint32_t eq_clk_l2_pos[] = {8, 9};
const uint32_t eq_clk_l3_pos[] = {6, 7};
const uint32_t SSH_REG_STOP_LEVEL = 8;
const uint32_t SSH_REG_STOP_LEVEL_LEN = 4;

// ----------------------------------------------------------------------
// Procedure Function
// ----------------------------------------------------------------------

fapi2::ReturnCode
p9_query_cache_access_state(
    const fapi2::Target<fapi2::TARGET_TYPE_EQ>& i_target,
    bool& o_l2_is_scomable,
    bool& o_l2_is_scannable,
    bool& o_l3_is_scomable,
    bool& o_l3_is_scannable)
{
    fapi2::buffer<uint64_t> l_qsshsrc;
    uint32_t l_quadStopLevel = 0;
    fapi2::buffer<uint64_t> l_data64;
    bool l_is_scomable = 1;
    uint8_t l_chpltNumber = 0;
    uint32_t l_exPos = 0;
    uint8_t l_execution_platform = 0;
    uint32_t l_stop_state_reg = 0;
    const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM;

    FAPI_INF("> p9_query_cache_access_state...");

    //Get the stop state from the SSHRC in the EQPPM
    //First figure out whether we should use the C_PPM_SSHFSP (if FSP platform) or C_PPM_SSHHYP (if HOST platform)
    FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_EXECUTION_PLATFORM, FAPI_SYSTEM, l_execution_platform),
             "Error: Failed to get platform");

    if (l_execution_platform == 0x02)
    {
        l_stop_state_reg =  C_PPM_SSHFSP;
    }
    else
    {
        l_stop_state_reg = C_PPM_SSHHYP;
    }

    FAPI_TRY(fapi2::getScom(i_target, l_stop_state_reg, l_qsshsrc), "Error reading data from QPPM SSHSRC");

    //A unit is scommable if clocks are running
    //A unit is scannable if the unit is powered up

    //Extract the core stop state
    l_qsshsrc.extractToRight<uint32_t>(l_quadStopLevel, SSH_REG_STOP_LEVEL, SSH_REG_STOP_LEVEL_LEN);

    FAPI_DBG("EQ Stop State: EQ(%d)", l_quadStopLevel);

    //Set all attribtes to 1, then clear them based on the stop state
    o_l2_is_scomable = 1;
    o_l2_is_scannable = 1;
    o_l3_is_scomable = 1;
    o_l3_is_scannable = 1;

    // STOP8 - Half Quad Deep Sleep
    //   VSU, ISU are powered off
    //   IFU, LSU are powered off
    //   PC, Core EPS are powered off
    //   L20-EX0 is clocked off if both cores are >= 8
    //   L20-EX1 is clocked off if both cores are >= 8
    if (l_quadStopLevel >= 8)
    {
        o_l2_is_scomable = 0;
    }

    // STOP9 - Fast Winkle (lab use only)
    // Both cores and cache are clocked off
    if (l_quadStopLevel >= 9)
    {
        o_l3_is_scomable = 0;
    }

    // STOP11 - Deep Winkle
    // Both cores and cache are powered off
    if (l_quadStopLevel >= 11)
    {
        o_l2_is_scannable = 0;
        o_l3_is_scannable = 0;
    }

    //Read clock status to confirm stop state history is accurate
    //If we trust the stop state history, this could be removed to save on code size
    //Compare Hardware status vs stop state status. If there is a mismatch the HW value overrides the stop state

    FAPI_TRY(fapi2::getScom(i_target, EQ_CLOCK_STAT_SL, l_data64), "Error reading data from EQ_CLOCK_STAT_SL");

    FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, i_target, l_chpltNumber),
             "Error: Failed to get the position of the EX:0x%08X", i_target);
    l_exPos = l_chpltNumber % 2;

    l_is_scomable = !l_data64.getBit(eq_clk_l2_pos[l_exPos]);

    if (o_l2_is_scomable != l_is_scomable)
    {
        FAPI_INF("Clock status didn't match stop state, overriding is_scomable status");
        o_l2_is_scomable = l_is_scomable;
    }

    l_is_scomable = !l_data64.getBit(eq_clk_l3_pos[l_exPos]);

    if (o_l3_is_scomable != l_is_scomable)
    {
        FAPI_INF("Clock status didn't match stop state, overriding is_scomable status");
        o_l3_is_scomable = l_is_scomable;
    }

fapi_try_exit:
    FAPI_INF("< p9_query_cache_access_state...");
    return fapi2::current_err;
}
<commit_msg>Update p9_query_cache_access_state to use the correct scom register<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/pm/p9_query_cache_access_state.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,2017                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file  p9_query_cache_access_state.C
/// @brief Check the stop level for the EX caches and sets boolean scomable parameters
///
// *HWP HWP Owner: Christina Graves <clgraves@us.ibm.com>
// *HWP Backup HWP Owner: Greg Still <stillgs@us.ibm.com>
// *HWP FW Owner:  Sangeetha T S <sangeet2@in.ibm.com>
// *HWP Team: PM
// *HWP Level: 2
// *HWP Consumed by: FSP:HS:SBE
///
///
///
/// @verbatim
/// High-level procedure flow:
///     - For the quad target, read the Stop State History register in the PPM
///       and use the actual stop level to determine if the quad has power and is being
///       clocked.
/// @endverbatim
///
//------------------------------------------------------------------------------

// ----------------------------------------------------------------------
// Includes
// ----------------------------------------------------------------------

#include <p9_quad_scom_addresses.H>
#include <p9_query_cache_access_state.H>

// ----------------------------------------------------------------------
// Constants
// ----------------------------------------------------------------------

const uint32_t eq_clk_l2_pos[] = {8, 9};
const uint32_t eq_clk_l3_pos[] = {6, 7};
const uint32_t SSH_REG_STOP_LEVEL = 8;
const uint32_t SSH_REG_STOP_LEVEL_LEN = 4;

// ----------------------------------------------------------------------
// Procedure Function
// ----------------------------------------------------------------------

fapi2::ReturnCode
p9_query_cache_access_state(
    const fapi2::Target<fapi2::TARGET_TYPE_EQ>& i_target,
    bool& o_l2_is_scomable,
    bool& o_l2_is_scannable,
    bool& o_l3_is_scomable,
    bool& o_l3_is_scannable)
{
    fapi2::buffer<uint64_t> l_qsshsrc;
    uint32_t l_quadStopLevel = 0;
    fapi2::buffer<uint64_t> l_data64;
    bool l_is_scomable = 1;
    uint8_t l_chpltNumber = 0;
    uint32_t l_exPos = 0;
    uint8_t l_execution_platform = 0;
    uint32_t l_stop_state_reg = 0;
    const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM;

    FAPI_INF("> p9_query_cache_access_state...");

    //Get the stop state from the SSHRC in the EQPPM
    //First figure out whether we should use the C_PPM_SSHFSP (if FSP platform) or C_PPM_SSHHYP (if HOST platform)
    FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_EXECUTION_PLATFORM, FAPI_SYSTEM, l_execution_platform),
             "Error: Failed to get platform");

    if (l_execution_platform == 0x02)
    {
        l_stop_state_reg =  EQ_PPM_SSHFSP;
    }
    else
    {
        l_stop_state_reg = EQ_PPM_SSHHYP;
    }

    FAPI_TRY(fapi2::getScom(i_target, l_stop_state_reg, l_qsshsrc), "Error reading data from QPPM SSHSRC");

    //A unit is scommable if clocks are running
    //A unit is scannable if the unit is powered up

    //Extract the core stop state
    l_qsshsrc.extractToRight<uint32_t>(l_quadStopLevel, SSH_REG_STOP_LEVEL, SSH_REG_STOP_LEVEL_LEN);

    FAPI_DBG("EQ Stop State: EQ(%d)", l_quadStopLevel);

    //Set all attribtes to 1, then clear them based on the stop state
    o_l2_is_scomable = 1;
    o_l2_is_scannable = 1;
    o_l3_is_scomable = 1;
    o_l3_is_scannable = 1;

    // STOP8 - Half Quad Deep Sleep
    //   VSU, ISU are powered off
    //   IFU, LSU are powered off
    //   PC, Core EPS are powered off
    //   L20-EX0 is clocked off if both cores are >= 8
    //   L20-EX1 is clocked off if both cores are >= 8
    if (l_quadStopLevel >= 8)
    {
        o_l2_is_scomable = 0;
    }

    // STOP9 - Fast Winkle (lab use only)
    // Both cores and cache are clocked off
    if (l_quadStopLevel >= 9)
    {
        o_l3_is_scomable = 0;
    }

    // STOP11 - Deep Winkle
    // Both cores and cache are powered off
    if (l_quadStopLevel >= 11)
    {
        o_l2_is_scannable = 0;
        o_l3_is_scannable = 0;
    }

    //Read clock status to confirm stop state history is accurate
    //If we trust the stop state history, this could be removed to save on code size
    //Compare Hardware status vs stop state status. If there is a mismatch the HW value overrides the stop state

    FAPI_TRY(fapi2::getScom(i_target, EQ_CLOCK_STAT_SL, l_data64), "Error reading data from EQ_CLOCK_STAT_SL");

    FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, i_target, l_chpltNumber),
             "Error: Failed to get the position of the EX:0x%08X", i_target);
    l_exPos = l_chpltNumber % 2;

    l_is_scomable = !l_data64.getBit(eq_clk_l2_pos[l_exPos]);

    if (o_l2_is_scomable != l_is_scomable)
    {
        FAPI_INF("Clock status didn't match stop state, overriding is_scomable status");
        o_l2_is_scomable = l_is_scomable;
    }

    l_is_scomable = !l_data64.getBit(eq_clk_l3_pos[l_exPos]);

    if (o_l3_is_scomable != l_is_scomable)
    {
        FAPI_INF("Clock status didn't match stop state, overriding is_scomable status");
        o_l3_is_scomable = l_is_scomable;
    }

fapi_try_exit:
    FAPI_INF("< p9_query_cache_access_state...");
    return fapi2::current_err;
}
<|endoftext|>