<commit_before>#include "Catch.hpp"

#include "RaZ/Math/Quaternion.hpp"

using namespace Raz::Literals;

namespace {

const Raz::Quaternionf quat1(10.0_deg, Raz::Axis::X);
const Raz::Quaternionf quat2(90.0_deg, 1.f, -2.f, 5.f);
const Raz::Quaternionf quat3(180.0_deg, 1.f, -2.f, 5.f);

} // namespace

TEST_CASE("Quaternion norm computation") {
  CHECK_THAT(quat1.computeSquaredNorm(), IsNearlyEqualTo(1.f));
  CHECK_THAT(quat1.computeNorm(), IsNearlyEqualTo(1.f));

  CHECK_THAT(quat2.computeSquaredNorm(), IsNearlyEqualTo(15.5f));
  CHECK_THAT(quat2.computeNorm(), IsNearlyEqualTo(3.93700385f));

  CHECK_THAT(quat3.computeSquaredNorm(), IsNearlyEqualTo(30.f));
  CHECK_THAT(quat3.computeNorm(), IsNearlyEqualTo(5.47722578f));
}

TEST_CASE("Quaternion matrix computation") {
  CHECK(quat1.computeMatrix() == Raz::Mat4f({{ 1.f,           0.f,          0.f, 0.f },
                                             { 0.f,   0.98480773f, 0.173648179f, 0.f },
                                             { 0.f, -0.173648179f,  0.98480773f, 0.f },
                                             { 0.f,           0.f,          0.f, 1.f }}));

  CHECK(quat2.computeMatrix() == Raz::Mat4f({{ -0.870967627f,   0.193548396f,   0.45161289f, 0.f },
                                             {  -0.45161289f,  -0.677419245f, -0.580645144f, 0.f },
                                             {  0.193548396f,  -0.709677398f,  0.677419424f, 0.f },
                                             {           0.f,            0.f,           0.f, 1.f }}));

  CHECK(quat3.computeMatrix() == Raz::Mat4f({{  -0.933333397f, -0.133333355f,  0.333333343f, 0.f },
                                             {  -0.133333325f, -0.733333409f, -0.666666687f, 0.f },
                                             {   0.333333343f, -0.666666687f,  0.666666627f, 0.f },
                                             {            0.f,           0.f,           0.f, 1.f }}));
}
<commit_msg>[Tests/Math/Quaternion] Check quaternion multiplication<commit_after>#include "Catch.hpp"

#include "RaZ/Math/Quaternion.hpp"

using namespace Raz::Literals;

namespace {

const Raz::Quaternionf quat1(10.0_deg, Raz::Axis::X);
const Raz::Quaternionf quat2(90.0_deg, 1.f, -2.f, 5.f);
const Raz::Quaternionf quat3(180.0_deg, 1.f, -2.f, 5.f);

} // namespace

TEST_CASE("Quaternion norm computation") {
  CHECK_THAT(quat1.computeSquaredNorm(), IsNearlyEqualTo(1.f));
  CHECK_THAT(quat1.computeNorm(), IsNearlyEqualTo(1.f));

  CHECK_THAT(quat2.computeSquaredNorm(), IsNearlyEqualTo(15.5f));
  CHECK_THAT(quat2.computeNorm(), IsNearlyEqualTo(3.93700385f));

  CHECK_THAT(quat3.computeSquaredNorm(), IsNearlyEqualTo(30.f));
  CHECK_THAT(quat3.computeNorm(), IsNearlyEqualTo(5.47722578f));
}

TEST_CASE("Quaternion matrix computation") {
  CHECK(quat1.computeMatrix() == Raz::Mat4f({{ 1.f,           0.f,          0.f, 0.f },
                                             { 0.f,   0.98480773f, 0.173648179f, 0.f },
                                             { 0.f, -0.173648179f,  0.98480773f, 0.f },
                                             { 0.f,           0.f,          0.f, 1.f }}));

  CHECK(quat2.computeMatrix() == Raz::Mat4f({{ -0.870967627f,   0.193548396f,   0.45161289f, 0.f },
                                             {  -0.45161289f,  -0.677419245f, -0.580645144f, 0.f },
                                             {  0.193548396f,  -0.709677398f,  0.677419424f, 0.f },
                                             {           0.f,            0.f,           0.f, 1.f }}));

  CHECK(quat3.computeMatrix() == Raz::Mat4f({{  -0.933333397f, -0.133333355f,  0.333333343f, 0.f },
                                             {  -0.133333325f, -0.733333409f, -0.666666687f, 0.f },
                                             {   0.333333343f, -0.666666687f,  0.666666627f, 0.f },
                                             {            0.f,           0.f,           0.f, 1.f }}));
}

TEST_CASE("Quaternion multiplication") {
  const auto quatUnit = Raz::Quaternionf::identity();
  const Raz::Quaternionf squareQuatUnit = quatUnit * quatUnit;
  CHECK(squareQuatUnit.computeMatrix() == quatUnit.computeMatrix());

  const Raz::Quaternionf quatRotx(45.0_deg, Raz::Axis::X);
  const Raz::Quaternionf mulRotx  = quatRotx * quatRotx.conjugate();
  CHECK(mulRotx.computeMatrix() == quatUnit.computeMatrix());

  const Raz::Quaternionf quatRoty(45.0_deg, Raz::Axis::Y);
  const Raz::Quaternionf mulRoty  = quatRoty * quatRoty.conjugate();
  CHECK(mulRoty.computeMatrix() == quatUnit.computeMatrix());

  const Raz::Quaternionf quatRotz(45.0_deg, Raz::Axis::Z);
  const Raz::Quaternionf mulRotz  = quatRotz * quatRotz.conjugate();
  CHECK(mulRotz.computeMatrix() == quatUnit.computeMatrix());

  /* From Wolfram Alpha:
   * https://www.wolframalpha.com/input/?i=quaternion%280.99619472%2C+0.0871557444%2C+0%2C+0%29+*+quaternion%280.707106769%2C+0.707106769%2C+-1.41421354%2C+3.53553391%29
   */
  const Raz::Quaternionf quat12 = quat1 * quat2;
  CHECK_THAT(quat12.computeNorm(), IsNearlyEqualTo(3.93700385f));
  const Raz::Mat4f expected = Raz::Mat4f({{ -0.870967627f,  0.112186f,  0.478361f, 0.f },
                                          {  -0.45161289f,   -0.5663f, -0.6894576, 0.f },
                                          {  0.193548396f, -0.816528f,  0.543894f, 0.f },
                                          {           0.f,        0.f,        0.f, 1.f }});
  const Raz::Mat4f result = quat12.computeMatrix();

  for(std::size_t i = 0; i < 16; ++i) {
    CHECK(result[i] == Approx(expected[i]));
  }
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: cdatasection.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: obo $ $Date: 2004-11-16 12:18:55 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2003 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _CDATASECTION_HXX
#define _CDATASECTION_HXX

#include <com/sun/star/uno/Reference.h>
#include <com/sun/star/uno/Exception.hpp>
#include <com/sun/star/xml/dom/XCDATASection.hpp>

#include "text.hxx"

using namespace rtl;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::xml::dom;

namespace DOM
{
    class CCDATASection : public cppu::ImplInheritanceHelper1< CText, XCDATASection >
    {
        friend class CNode;
    protected:
        CCDATASection(const xmlNodePtr aNodePtr);

    public:
        virtual Reference< XText > SAL_CALL splitText(sal_Int32 offset)
             throw (RuntimeException)
        {
            return CText::splitText(offset);
        }

         // --- delegations for XCharacterData
        virtual void SAL_CALL appendData(const OUString& arg)
            throw (DOMException)
        {
            CCharacterData::appendData(arg);
        }
        virtual void SAL_CALL deleteData(sal_Int32 offset, sal_Int32 count)
            throw (DOMException)
        {
            CCharacterData::deleteData(offset, count);
        }
        virtual OUString SAL_CALL getData() throw (RuntimeException)
        {
            return CCharacterData::getData();
        }
        virtual sal_Int32 SAL_CALL getLength() throw (RuntimeException)
        {
            return CCharacterData::getLength();
        }
        virtual void SAL_CALL insertData(sal_Int32 offset, const OUString& arg)
            throw (DOMException)
        {
            CCharacterData::insertData(offset, arg);
        }
        virtual void SAL_CALL replaceData(sal_Int32 offset, sal_Int32 count, const OUString& arg)
            throw (DOMException)
        {
            CCharacterData::replaceData(offset, count, arg);
        }
        virtual void SAL_CALL setData(const OUString& data)
            throw (DOMException)
        {
            CCharacterData::setData(data);
        }
        virtual OUString SAL_CALL subStringData(sal_Int32 offset, sal_Int32 count)
            throw (DOMException)
        {
            return CCharacterData::subStringData(offset, count);
        }

         // --- overrides for XNode base
        virtual OUString SAL_CALL getNodeName()
            throw (RuntimeException);
        virtual OUString SAL_CALL getNodeValue()
            throw (RuntimeException);

    // --- delegation for XNde base.
    virtual Reference< XNode > SAL_CALL appendChild(const Reference< XNode >& newChild)
        throw (DOMException)
    {
        return CNode::appendChild(newChild);
    }
    virtual Reference< XNode > SAL_CALL cloneNode(sal_Bool deep)
        throw (RuntimeException)
    {
        return CNode::cloneNode(deep);
    }
    virtual Reference< XNamedNodeMap > SAL_CALL getAttributes()
        throw (RuntimeException)
    {
        return CNode::getAttributes();
    }
    virtual Reference< XNodeList > SAL_CALL getChildNodes()
        throw (RuntimeException)
    {
        return CNode::getChildNodes();
    }
    virtual Reference< XNode > SAL_CALL getFirstChild()
        throw (RuntimeException)
    {
        return CNode::getFirstChild();
    }
    virtual Reference< XNode > SAL_CALL getLastChild()
        throw (RuntimeException)
    {
        return CNode::getLastChild();
    }
    virtual OUString SAL_CALL getLocalName()
        throw (RuntimeException)
    {
        return CNode::getLocalName();
    }
    virtual OUString SAL_CALL getNamespaceURI()
        throw (RuntimeException)
    {
        return CNode::getNamespaceURI();
    }
    virtual Reference< XNode > SAL_CALL getNextSibling()
        throw (RuntimeException)
    {
        return CNode::getNextSibling();
    }
    virtual NodeType SAL_CALL getNodeType()
        throw (RuntimeException)
    {
        return CNode::getNodeType();
    }
    virtual Reference< XDocument > SAL_CALL getOwnerDocument()
        throw (RuntimeException)
    {
        return CNode::getOwnerDocument();
    }
    virtual Reference< XNode > SAL_CALL getParentNode()
        throw (RuntimeException)
    {
        return CNode::getParentNode();
    }
    virtual OUString SAL_CALL getPrefix()
        throw (RuntimeException)
    {
        return CNode::getPrefix();
    }
    virtual Reference< XNode > SAL_CALL getPreviousSibling()
        throw (RuntimeException)
    {
        return CNode::getPreviousSibling();
    }
    virtual sal_Bool SAL_CALL hasAttributes()
        throw (RuntimeException)
    {
        return CNode::hasAttributes();
    }
    virtual sal_Bool SAL_CALL hasChildNodes()
        throw (RuntimeException)
    {
        return CNode::hasChildNodes();
    }
    virtual Reference< XNode > SAL_CALL insertBefore(
            const Reference< XNode >& newChild, const Reference< XNode >& refChild)
        throw (DOMException)
    {
        return CNode::insertBefore(newChild, refChild);
    }
    virtual sal_Bool SAL_CALL isSupported(const OUString& feature, const OUString& ver)
        throw (RuntimeException)
    {
        return CNode::isSupported(feature, ver);
    }
    virtual void SAL_CALL normalize()
        throw (RuntimeException)
    {
        CNode::normalize();
    }
    virtual Reference< XNode > SAL_CALL removeChild(const Reference< XNode >& oldChild)
        throw (DOMException)
    {
        return CNode::removeChild(oldChild);
    }
    virtual Reference< XNode > SAL_CALL replaceChild(
            const Reference< XNode >& newChild, const Reference< XNode >& oldChild)
        throw (DOMException)
    {
        return CNode::replaceChild(newChild, oldChild);
    }
    virtual void SAL_CALL setNodeValue(const OUString& nodeValue)
        throw (DOMException)
    {
        return CNode::setNodeValue(nodeValue);
    }
    virtual void SAL_CALL setPrefix(const OUString& prefix)
        throw (DOMException)
    {
        return CNode::setPrefix(prefix);
    }

    };

}

#endif
<commit_msg>INTEGRATION: CWS ooo19126 (1.3.12); FILE MERGED 2005/09/05 17:19:55 rt 1.3.12.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: cdatasection.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 09:55:24 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _CDATASECTION_HXX
#define _CDATASECTION_HXX

#include <com/sun/star/uno/Reference.h>
#include <com/sun/star/uno/Exception.hpp>
#include <com/sun/star/xml/dom/XCDATASection.hpp>

#include "text.hxx"

using namespace rtl;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::xml::dom;

namespace DOM
{
    class CCDATASection : public cppu::ImplInheritanceHelper1< CText, XCDATASection >
    {
        friend class CNode;
    protected:
        CCDATASection(const xmlNodePtr aNodePtr);

    public:
        virtual Reference< XText > SAL_CALL splitText(sal_Int32 offset)
             throw (RuntimeException)
        {
            return CText::splitText(offset);
        }

         // --- delegations for XCharacterData
        virtual void SAL_CALL appendData(const OUString& arg)
            throw (DOMException)
        {
            CCharacterData::appendData(arg);
        }
        virtual void SAL_CALL deleteData(sal_Int32 offset, sal_Int32 count)
            throw (DOMException)
        {
            CCharacterData::deleteData(offset, count);
        }
        virtual OUString SAL_CALL getData() throw (RuntimeException)
        {
            return CCharacterData::getData();
        }
        virtual sal_Int32 SAL_CALL getLength() throw (RuntimeException)
        {
            return CCharacterData::getLength();
        }
        virtual void SAL_CALL insertData(sal_Int32 offset, const OUString& arg)
            throw (DOMException)
        {
            CCharacterData::insertData(offset, arg);
        }
        virtual void SAL_CALL replaceData(sal_Int32 offset, sal_Int32 count, const OUString& arg)
            throw (DOMException)
        {
            CCharacterData::replaceData(offset, count, arg);
        }
        virtual void SAL_CALL setData(const OUString& data)
            throw (DOMException)
        {
            CCharacterData::setData(data);
        }
        virtual OUString SAL_CALL subStringData(sal_Int32 offset, sal_Int32 count)
            throw (DOMException)
        {
            return CCharacterData::subStringData(offset, count);
        }

         // --- overrides for XNode base
        virtual OUString SAL_CALL getNodeName()
            throw (RuntimeException);
        virtual OUString SAL_CALL getNodeValue()
            throw (RuntimeException);

    // --- delegation for XNde base.
    virtual Reference< XNode > SAL_CALL appendChild(const Reference< XNode >& newChild)
        throw (DOMException)
    {
        return CNode::appendChild(newChild);
    }
    virtual Reference< XNode > SAL_CALL cloneNode(sal_Bool deep)
        throw (RuntimeException)
    {
        return CNode::cloneNode(deep);
    }
    virtual Reference< XNamedNodeMap > SAL_CALL getAttributes()
        throw (RuntimeException)
    {
        return CNode::getAttributes();
    }
    virtual Reference< XNodeList > SAL_CALL getChildNodes()
        throw (RuntimeException)
    {
        return CNode::getChildNodes();
    }
    virtual Reference< XNode > SAL_CALL getFirstChild()
        throw (RuntimeException)
    {
        return CNode::getFirstChild();
    }
    virtual Reference< XNode > SAL_CALL getLastChild()
        throw (RuntimeException)
    {
        return CNode::getLastChild();
    }
    virtual OUString SAL_CALL getLocalName()
        throw (RuntimeException)
    {
        return CNode::getLocalName();
    }
    virtual OUString SAL_CALL getNamespaceURI()
        throw (RuntimeException)
    {
        return CNode::getNamespaceURI();
    }
    virtual Reference< XNode > SAL_CALL getNextSibling()
        throw (RuntimeException)
    {
        return CNode::getNextSibling();
    }
    virtual NodeType SAL_CALL getNodeType()
        throw (RuntimeException)
    {
        return CNode::getNodeType();
    }
    virtual Reference< XDocument > SAL_CALL getOwnerDocument()
        throw (RuntimeException)
    {
        return CNode::getOwnerDocument();
    }
    virtual Reference< XNode > SAL_CALL getParentNode()
        throw (RuntimeException)
    {
        return CNode::getParentNode();
    }
    virtual OUString SAL_CALL getPrefix()
        throw (RuntimeException)
    {
        return CNode::getPrefix();
    }
    virtual Reference< XNode > SAL_CALL getPreviousSibling()
        throw (RuntimeException)
    {
        return CNode::getPreviousSibling();
    }
    virtual sal_Bool SAL_CALL hasAttributes()
        throw (RuntimeException)
    {
        return CNode::hasAttributes();
    }
    virtual sal_Bool SAL_CALL hasChildNodes()
        throw (RuntimeException)
    {
        return CNode::hasChildNodes();
    }
    virtual Reference< XNode > SAL_CALL insertBefore(
            const Reference< XNode >& newChild, const Reference< XNode >& refChild)
        throw (DOMException)
    {
        return CNode::insertBefore(newChild, refChild);
    }
    virtual sal_Bool SAL_CALL isSupported(const OUString& feature, const OUString& ver)
        throw (RuntimeException)
    {
        return CNode::isSupported(feature, ver);
    }
    virtual void SAL_CALL normalize()
        throw (RuntimeException)
    {
        CNode::normalize();
    }
    virtual Reference< XNode > SAL_CALL removeChild(const Reference< XNode >& oldChild)
        throw (DOMException)
    {
        return CNode::removeChild(oldChild);
    }
    virtual Reference< XNode > SAL_CALL replaceChild(
            const Reference< XNode >& newChild, const Reference< XNode >& oldChild)
        throw (DOMException)
    {
        return CNode::replaceChild(newChild, oldChild);
    }
    virtual void SAL_CALL setNodeValue(const OUString& nodeValue)
        throw (DOMException)
    {
        return CNode::setNodeValue(nodeValue);
    }
    virtual void SAL_CALL setPrefix(const OUString& prefix)
        throw (DOMException)
    {
        return CNode::setPrefix(prefix);
    }

    };

}

#endif
<|endoftext|>


<commit_before>// This file is a part of the OpenSurgSim project.
// Copyright 2013, SimQuest Solutions Inc.
//
// 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.

#include <memory>
#include <boost/thread.hpp>

#include "SurgSim/Blocks/BasicSceneElement.h"
#include "SurgSim/Blocks/TransferPoseBehavior.h"
#include "SurgSim/Blocks/TransferInputPoseBehavior.h"
#include "SurgSim/Devices/MultiAxis/MultiAxisDevice.h"
#include "SurgSim/Framework/BehaviorManager.h"
#include "SurgSim/Framework/Log.h"
#include "SurgSim/Framework/Runtime.h"
#include "SurgSim/Framework/Scene.h"
#include "SurgSim/Framework/SceneElement.h"
#include "SurgSim/Graphics/OsgBoxRepresentation.h"
#include "SurgSim/Graphics/OsgCamera.h"
#include "SurgSim/Graphics/OsgManager.h"
#include "SurgSim/Graphics/OsgMaterial.h"
#include "SurgSim/Graphics/OsgPlaneRepresentation.h"
#include "SurgSim/Graphics/OsgShader.h"
#include "SurgSim/Graphics/OsgUniform.h"
#include "SurgSim/Graphics/OsgView.h"
#include "SurgSim/Graphics/OsgViewElement.h"
#include "SurgSim/Input/InputManager.h"
#include "SurgSim/Math/BoxShape.h"
#include "SurgSim/Math/DoubleSidedPlaneShape.h"
#include "SurgSim/Math/Quaternion.h"
#include "SurgSim/Math/RigidTransform.h"
#include "SurgSim/Math/Vector.h"
#include "SurgSim/Physics/PhysicsManager.h"
#include "SurgSim/Physics/FixedRepresentation.h"
#include "SurgSim/Physics/RigidRepresentationParameters.h"
#include "SurgSim/Collision/RigidCollisionRepresentation.h"
#include "SurgSim/Physics/VirtualToolCoupler.h"

using SurgSim::Blocks::BasicSceneElement;
using SurgSim::Blocks::TransferPoseBehavior;
using SurgSim::Blocks::TransferInputPoseBehavior;
using SurgSim::Framework::Logger;
using SurgSim::Framework::SceneElement;
using SurgSim::Graphics::OsgBoxRepresentation;
using SurgSim::Graphics::OsgMaterial;
using SurgSim::Graphics::OsgPlaneRepresentation;
using SurgSim::Graphics::OsgShader;
using SurgSim::Graphics::OsgUniform;
using SurgSim::Math::BoxShape;
using SurgSim::Math::DoubleSidedPlaneShape;
using SurgSim::Math::Vector4f;
using SurgSim::Math::Vector3d;
using SurgSim::Physics::FixedRepresentation;
using SurgSim::Physics::Representation;
using SurgSim::Physics::RigidRepresentation;
using SurgSim::Physics::PhysicsManager;
using SurgSim::Physics::VirtualToolCoupler;
using SurgSim::Physics::RigidRepresentationParameters;

std::shared_ptr<SurgSim::Graphics::ViewElement> createView(const std::string& name, int x, int y, int width, int height)
{
	using SurgSim::Graphics::OsgViewElement;

	std::shared_ptr<OsgViewElement> viewElement = std::make_shared<OsgViewElement>(name);
	viewElement->getView()->setPosition(x, y);
	viewElement->getView()->setDimensions(width, height);

	return viewElement;
}

std::shared_ptr<SceneElement> createPlane(const std::string& name,
										  const SurgSim::Math::RigidTransform3d& pose)
{
	std::shared_ptr<DoubleSidedPlaneShape> planeShape = std::make_shared<DoubleSidedPlaneShape>();

	std::shared_ptr<FixedRepresentation> physicsRepresentation =
		std::make_shared<FixedRepresentation>(name + " Physics");
	RigidRepresentationParameters params;
	params.setShapeUsedForMassInertia(planeShape);
	physicsRepresentation->setInitialParameters(params);
	physicsRepresentation->setInitialPose(pose);

	std::shared_ptr<OsgPlaneRepresentation> graphicsRepresentation =
		std::make_shared<OsgPlaneRepresentation>(name + " Graphics");
	graphicsRepresentation->setInitialPose(pose);

	std::shared_ptr<OsgMaterial> material = std::make_shared<OsgMaterial>();
	std::shared_ptr<OsgShader> shader = std::make_shared<OsgShader>();

	std::shared_ptr<OsgUniform<Vector4f>> uniform = std::make_shared<OsgUniform<Vector4f>>("color");
	uniform->set(Vector4f(0.0f, 0.6f, 1.0f, 0.0f));
	material->addUniform(uniform);

	shader->setFragmentShaderSource(
		"uniform vec4 color;\n"
		"void main(void)\n"
		"{\n"
		"	gl_FragColor = color;\n"
		"}");
	material->setShader(shader);
	graphicsRepresentation->setMaterial(material);

	std::shared_ptr<SceneElement> planeElement = std::make_shared<BasicSceneElement>(name);
	planeElement->addComponent(physicsRepresentation);
	planeElement->addComponent(graphicsRepresentation);

	auto transferPose = std::make_shared<TransferPoseBehavior>("Physics to Graphics Pose");
	transferPose->setPoseSender(physicsRepresentation);
	transferPose->setPoseReceiver(graphicsRepresentation);
	planeElement->addComponent(transferPose);
	auto collisionRepresentation =  std::make_shared<SurgSim::Collision::RigidCollisionRepresentation>
		("Plane Collision");
	collisionRepresentation->setRigidRepresentation(physicsRepresentation);
	planeElement->addComponent(collisionRepresentation);
	return planeElement;
}

std::shared_ptr<SceneElement> createBox(const std::string& name)
{
	RigidRepresentationParameters params;
	params.setDensity(700.0); // Wood in Kg.m-3
	std::shared_ptr<BoxShape> box = std::make_shared<BoxShape>(0.8, 2.0, 0.2); // in m
	params.setShapeUsedForMassInertia(box);

	std::shared_ptr<RigidRepresentation> physicsRepresentation =
		std::make_shared<RigidRepresentation>(name + "-Physics");
	physicsRepresentation->setInitialParameters(params);

	std::shared_ptr<OsgBoxRepresentation> graphicsRepresentation =
		std::make_shared<OsgBoxRepresentation>(name + "-Graphics");
	graphicsRepresentation->setSize(box->getSizeX(), box->getSizeY(), box->getSizeZ());

	std::shared_ptr<OsgBoxRepresentation> rawInputGraphicsRepresentation =
		std::make_shared<OsgBoxRepresentation>(name + "-RawInput-Graphics");
	rawInputGraphicsRepresentation->setSize(box->getSizeX(), box->getSizeY(), box->getSizeZ());

	std::shared_ptr<OsgMaterial> material = std::make_shared<OsgMaterial>();
	std::shared_ptr<OsgShader> shader = std::make_shared<OsgShader>();
	shader->setVertexShaderSource(
		"void main(void)\n"
		"{\n"
		"    gl_Position = ftransform();\n"
		"}");
	shader->setFragmentShaderSource(
		"void main(void)\n"
		"{\n"
		"    gl_FragColor = vec4(0.2, 0.2, 0.2, 1.0);\n"
		"}");
	material->setShader(shader);
	rawInputGraphicsRepresentation->setMaterial(material);

	std::shared_ptr<SurgSim::Input::InputComponent> inputComponent =
		std::make_shared<SurgSim::Input::InputComponent>("input");
	inputComponent->setDeviceName("MultiAxisDevice");
	// The vtc parameters control the spring between the device and the simulated rigid body.
	// To understand how they are used, let's have a look at the physics under the hood.
	// For a given spring between points A and B, of stiffness k and damping c, we have the Newton's law:
	// m.a = F = k.AB - c.d(AB)/dt
	// It is clear that the mass of the object has a direct inverse relationship with the spring
	// stiffness and damping parameters. Therefore, if a set of parameters (k/c) behaves well for an object
	// of mass m, an object of mass 2m will need a vtc with the parameters (2k/2c) to behave the same way
	// on the physical system. The mass factor helps to scale the vtc parameters easily to different objects.
	// The actual values of the vtc parameters are experimental and needs to be tweaked for each application.
	std::shared_ptr<VirtualToolCoupler> inputCoupler =
		std::make_shared<VirtualToolCoupler>("Input Coupler", inputComponent, physicsRepresentation);
	inputCoupler->setAngularDamping(params.getMass() * 20);
	inputCoupler->setAngularStiffness(params.getMass() * 50);
	inputCoupler->setLinearDamping(params.getMass() * 50);
	inputCoupler->setLinearStiffness(params.getMass() * 200);

	std::shared_ptr<SceneElement> boxElement = std::make_shared<BasicSceneElement>(name);
	boxElement->addComponent(physicsRepresentation);
	boxElement->addComponent(graphicsRepresentation);
	boxElement->addComponent(rawInputGraphicsRepresentation);
	boxElement->addComponent(inputComponent);
	boxElement->addComponent(inputCoupler);
	auto transferPose = std::make_shared<TransferPoseBehavior>("Physics to Graphics");
	transferPose->setPoseSender(physicsRepresentation);
	transferPose->setPoseReceiver(graphicsRepresentation);
	boxElement->addComponent(transferPose);
	auto collisionRepresentation = std::make_shared<SurgSim::Collision::RigidCollisionRepresentation>
		("Box Collision Representation");
	collisionRepresentation->setRigidRepresentation(physicsRepresentation);
	boxElement->addComponent(collisionRepresentation);
	return boxElement;
}

int main(int argc, char* argv[])
{
	std::shared_ptr<SurgSim::Graphics::OsgManager> graphicsManager = std::make_shared<SurgSim::Graphics::OsgManager>();
	std::shared_ptr<PhysicsManager> physicsManager = std::make_shared<PhysicsManager>();
	std::shared_ptr<SurgSim::Framework::BehaviorManager> behaviorManager =
		std::make_shared<SurgSim::Framework::BehaviorManager>();
	std::shared_ptr<SurgSim::Input::InputManager> inputManager = std::make_shared<SurgSim::Input::InputManager>();

	////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	std::shared_ptr<SurgSim::Device::MultiAxisDevice> toolDevice =
		std::make_shared<SurgSim::Device::MultiAxisDevice>("MultiAxisDevice");
	toolDevice->setPositionScale(toolDevice->getPositionScale() * 10.0);
	toolDevice->setOrientationScale(toolDevice->getOrientationScale() * 3.0);
	SURGSIM_ASSERT( toolDevice->initialize() == true ) <<
		"Could not initialize device '%s' for the tool.\n", toolDevice->getName().c_str();

	inputManager->addDevice(toolDevice);
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	std::shared_ptr<SurgSim::Framework::Runtime> runtime(new SurgSim::Framework::Runtime());
	runtime->addManager(physicsManager);
	runtime->addManager(graphicsManager);
	runtime->addManager(behaviorManager);
	runtime->addManager(inputManager);

	std::shared_ptr<SurgSim::Framework::Scene> scene = runtime->getScene();
	scene->addSceneElement(createBox("box"));
	scene->addSceneElement(createPlane("plane",
		SurgSim::Math::makeRigidTransform(SurgSim::Math::Quaterniond::Identity(), Vector3d(0.0, -1.0, 0.0))));
	scene->addSceneElement(createView("view", 0, 0, 1023, 768));

	graphicsManager->getDefaultCamera()->setInitialPose(
		SurgSim::Math::makeRigidTransform(SurgSim::Math::Quaterniond::Identity(), Vector3d(0.0, 0.5, 5.0)));

	runtime->execute();

	return 0;
}
<commit_msg>Bugfix: couples input pose to rawGraphicsRepresentation in VTC example.<commit_after>// This file is a part of the OpenSurgSim project.
// Copyright 2013, SimQuest Solutions Inc.
//
// 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.

#include <memory>
#include <boost/thread.hpp>

#include "SurgSim/Blocks/BasicSceneElement.h"
#include "SurgSim/Blocks/TransferPoseBehavior.h"
#include "SurgSim/Blocks/TransferInputPoseBehavior.h"
#include "SurgSim/Devices/MultiAxis/MultiAxisDevice.h"
#include "SurgSim/Framework/BehaviorManager.h"
#include "SurgSim/Framework/Log.h"
#include "SurgSim/Framework/Runtime.h"
#include "SurgSim/Framework/Scene.h"
#include "SurgSim/Framework/SceneElement.h"
#include "SurgSim/Graphics/OsgBoxRepresentation.h"
#include "SurgSim/Graphics/OsgCamera.h"
#include "SurgSim/Graphics/OsgManager.h"
#include "SurgSim/Graphics/OsgMaterial.h"
#include "SurgSim/Graphics/OsgPlaneRepresentation.h"
#include "SurgSim/Graphics/OsgShader.h"
#include "SurgSim/Graphics/OsgUniform.h"
#include "SurgSim/Graphics/OsgView.h"
#include "SurgSim/Graphics/OsgViewElement.h"
#include "SurgSim/Input/InputManager.h"
#include "SurgSim/Math/BoxShape.h"
#include "SurgSim/Math/DoubleSidedPlaneShape.h"
#include "SurgSim/Math/Quaternion.h"
#include "SurgSim/Math/RigidTransform.h"
#include "SurgSim/Math/Vector.h"
#include "SurgSim/Physics/PhysicsManager.h"
#include "SurgSim/Physics/FixedRepresentation.h"
#include "SurgSim/Physics/RigidRepresentationParameters.h"
#include "SurgSim/Collision/RigidCollisionRepresentation.h"
#include "SurgSim/Physics/VirtualToolCoupler.h"

using SurgSim::Blocks::BasicSceneElement;
using SurgSim::Blocks::TransferPoseBehavior;
using SurgSim::Blocks::TransferInputPoseBehavior;
using SurgSim::Framework::Logger;
using SurgSim::Framework::SceneElement;
using SurgSim::Graphics::OsgBoxRepresentation;
using SurgSim::Graphics::OsgMaterial;
using SurgSim::Graphics::OsgPlaneRepresentation;
using SurgSim::Graphics::OsgShader;
using SurgSim::Graphics::OsgUniform;
using SurgSim::Math::BoxShape;
using SurgSim::Math::DoubleSidedPlaneShape;
using SurgSim::Math::Vector4f;
using SurgSim::Math::Vector3d;
using SurgSim::Physics::FixedRepresentation;
using SurgSim::Physics::Representation;
using SurgSim::Physics::RigidRepresentation;
using SurgSim::Physics::PhysicsManager;
using SurgSim::Physics::VirtualToolCoupler;
using SurgSim::Physics::RigidRepresentationParameters;

std::shared_ptr<SurgSim::Graphics::ViewElement> createView(const std::string& name, int x, int y, int width, int height)
{
	using SurgSim::Graphics::OsgViewElement;

	std::shared_ptr<OsgViewElement> viewElement = std::make_shared<OsgViewElement>(name);
	viewElement->getView()->setPosition(x, y);
	viewElement->getView()->setDimensions(width, height);

	return viewElement;
}

std::shared_ptr<SceneElement> createPlane(const std::string& name,
										  const SurgSim::Math::RigidTransform3d& pose)
{
	std::shared_ptr<DoubleSidedPlaneShape> planeShape = std::make_shared<DoubleSidedPlaneShape>();

	std::shared_ptr<FixedRepresentation> physicsRepresentation =
		std::make_shared<FixedRepresentation>(name + " Physics");
	RigidRepresentationParameters params;
	params.setShapeUsedForMassInertia(planeShape);
	physicsRepresentation->setInitialParameters(params);
	physicsRepresentation->setInitialPose(pose);

	std::shared_ptr<OsgPlaneRepresentation> graphicsRepresentation =
		std::make_shared<OsgPlaneRepresentation>(name + " Graphics");
	graphicsRepresentation->setInitialPose(pose);

	std::shared_ptr<OsgMaterial> material = std::make_shared<OsgMaterial>();
	std::shared_ptr<OsgShader> shader = std::make_shared<OsgShader>();

	std::shared_ptr<OsgUniform<Vector4f>> uniform = std::make_shared<OsgUniform<Vector4f>>("color");
	uniform->set(Vector4f(0.0f, 0.6f, 1.0f, 0.0f));
	material->addUniform(uniform);

	shader->setFragmentShaderSource(
		"uniform vec4 color;\n"
		"void main(void)\n"
		"{\n"
		"	gl_FragColor = color;\n"
		"}");
	material->setShader(shader);
	graphicsRepresentation->setMaterial(material);

	std::shared_ptr<SceneElement> planeElement = std::make_shared<BasicSceneElement>(name);
	planeElement->addComponent(physicsRepresentation);
	planeElement->addComponent(graphicsRepresentation);

	auto transferPose = std::make_shared<TransferPoseBehavior>("Physics to Graphics Pose");
	transferPose->setPoseSender(physicsRepresentation);
	transferPose->setPoseReceiver(graphicsRepresentation);
	planeElement->addComponent(transferPose);
	auto collisionRepresentation =  std::make_shared<SurgSim::Collision::RigidCollisionRepresentation>
		("Plane Collision");
	collisionRepresentation->setRigidRepresentation(physicsRepresentation);
	planeElement->addComponent(collisionRepresentation);
	return planeElement;
}

std::shared_ptr<SceneElement> createBox(const std::string& name)
{
	RigidRepresentationParameters params;
	params.setDensity(700.0); // Wood in Kg.m-3
	std::shared_ptr<BoxShape> box = std::make_shared<BoxShape>(0.8, 2.0, 0.2); // in m
	params.setShapeUsedForMassInertia(box);

	std::shared_ptr<RigidRepresentation> physicsRepresentation =
		std::make_shared<RigidRepresentation>(name + "-Physics");
	physicsRepresentation->setInitialParameters(params);

	std::shared_ptr<OsgBoxRepresentation> graphicsRepresentation =
		std::make_shared<OsgBoxRepresentation>(name + "-Graphics");
	graphicsRepresentation->setSize(box->getSizeX(), box->getSizeY(), box->getSizeZ());

	std::shared_ptr<OsgBoxRepresentation> rawInputGraphicsRepresentation =
		std::make_shared<OsgBoxRepresentation>(name + "-RawInput-Graphics");
	rawInputGraphicsRepresentation->setSize(box->getSizeX(), box->getSizeY(), box->getSizeZ());

	std::shared_ptr<OsgMaterial> material = std::make_shared<OsgMaterial>();
	std::shared_ptr<OsgShader> shader = std::make_shared<OsgShader>();
	shader->setVertexShaderSource(
		"void main(void)\n"
		"{\n"
		"    gl_Position = ftransform();\n"
		"}");
	shader->setFragmentShaderSource(
		"void main(void)\n"
		"{\n"
		"    gl_FragColor = vec4(0.2, 0.2, 0.2, 1.0);\n"
		"}");
	material->setShader(shader);
	rawInputGraphicsRepresentation->setMaterial(material);

	std::shared_ptr<SurgSim::Input::InputComponent> inputComponent =
		std::make_shared<SurgSim::Input::InputComponent>("input");
	inputComponent->setDeviceName("MultiAxisDevice");
	// The vtc parameters control the spring between the device and the simulated rigid body.
	// To understand how they are used, let's have a look at the physics under the hood.
	// For a given spring between points A and B, of stiffness k and damping c, we have the Newton's law:
	// m.a = F = k.AB - c.d(AB)/dt
	// It is clear that the mass of the object has a direct inverse relationship with the spring
	// stiffness and damping parameters. Therefore, if a set of parameters (k/c) behaves well for an object
	// of mass m, an object of mass 2m will need a vtc with the parameters (2k/2c) to behave the same way
	// on the physical system. The mass factor helps to scale the vtc parameters easily to different objects.
	// The actual values of the vtc parameters are experimental and needs to be tweaked for each application.
	std::shared_ptr<VirtualToolCoupler> inputCoupler =
		std::make_shared<VirtualToolCoupler>("Input Coupler", inputComponent, physicsRepresentation);
	inputCoupler->setAngularDamping(params.getMass() * 20);
	inputCoupler->setAngularStiffness(params.getMass() * 50);
	inputCoupler->setLinearDamping(params.getMass() * 50);
	inputCoupler->setLinearStiffness(params.getMass() * 200);

	std::shared_ptr<SceneElement> boxElement = std::make_shared<BasicSceneElement>(name);
	boxElement->addComponent(physicsRepresentation);
	boxElement->addComponent(graphicsRepresentation);
	boxElement->addComponent(rawInputGraphicsRepresentation);
	boxElement->addComponent(inputComponent);
	boxElement->addComponent(inputCoupler);
	auto transferPose = std::make_shared<TransferPoseBehavior>("Physics to Graphics");
	transferPose->setPoseSender(physicsRepresentation);
	transferPose->setPoseReceiver(graphicsRepresentation);
	boxElement->addComponent(transferPose);
	auto transferInputPose = std::make_shared<TransferInputPoseBehavior>("Input to RawGraphics");
	transferInputPose->setPoseSender(inputComponent);
	transferInputPose->setPoseReceiver(rawInputGraphicsRepresentation);
	boxElement->addComponent(transferInputPose);
	auto collisionRepresentation = std::make_shared<SurgSim::Collision::RigidCollisionRepresentation>
		("Box Collision Representation");
	collisionRepresentation->setRigidRepresentation(physicsRepresentation);
	boxElement->addComponent(collisionRepresentation);
	return boxElement;
}

int main(int argc, char* argv[])
{
	std::shared_ptr<SurgSim::Graphics::OsgManager> graphicsManager = std::make_shared<SurgSim::Graphics::OsgManager>();
	std::shared_ptr<PhysicsManager> physicsManager = std::make_shared<PhysicsManager>();
	std::shared_ptr<SurgSim::Framework::BehaviorManager> behaviorManager =
		std::make_shared<SurgSim::Framework::BehaviorManager>();
	std::shared_ptr<SurgSim::Input::InputManager> inputManager = std::make_shared<SurgSim::Input::InputManager>();

	////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	std::shared_ptr<SurgSim::Device::MultiAxisDevice> toolDevice =
		std::make_shared<SurgSim::Device::MultiAxisDevice>("MultiAxisDevice");
	toolDevice->setPositionScale(toolDevice->getPositionScale() * 10.0);
	toolDevice->setOrientationScale(toolDevice->getOrientationScale() * 3.0);
	SURGSIM_ASSERT( toolDevice->initialize() == true ) <<
		"Could not initialize device '%s' for the tool.\n", toolDevice->getName().c_str();

	inputManager->addDevice(toolDevice);
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	std::shared_ptr<SurgSim::Framework::Runtime> runtime(new SurgSim::Framework::Runtime());
	runtime->addManager(physicsManager);
	runtime->addManager(graphicsManager);
	runtime->addManager(behaviorManager);
	runtime->addManager(inputManager);

	std::shared_ptr<SurgSim::Framework::Scene> scene = runtime->getScene();
	scene->addSceneElement(createBox("box"));
	scene->addSceneElement(createPlane("plane",
		SurgSim::Math::makeRigidTransform(SurgSim::Math::Quaterniond::Identity(), Vector3d(0.0, -1.0, 0.0))));
	scene->addSceneElement(createView("view", 0, 0, 1023, 768));

	graphicsManager->getDefaultCamera()->setInitialPose(
		SurgSim::Math::makeRigidTransform(SurgSim::Math::Quaterniond::Identity(), Vector3d(0.0, 0.5, 5.0)));

	runtime->execute();

	return 0;
}
<|endoftext|>


<commit_before>#include <TCPSocket.h>

#include <iostream>

using namespace NET;

static char recv_msg[50];

int main()
{
	try {

	TCPSocket client_socket;
	client_socket.connect( "127.0.0.1", 47777);

	// wait for data within the next 5s
	int bytes_recv = client_socket.timedReceive( recv_msg, 50, 5000);

	// we got a message!
	if(bytes_recv > 0)
		std::cout << "Received data from server: " << recv_msg << std::endl;

	// this is optional, we could simply do nothing here
	client_socket.disconnect();

	// if something fails, we get here
	} catch( const NET::SocketException& e)
	{
		std::cerr << e.what() << std::endl;
		return 1;
	}

	return 0;
}
<commit_msg>don't use namespace in examples<commit_after>#include <TCPSocket.h>

#include <iostream>

static char recv_msg[50];

int main()
{
	try {

	NET::TCPSocket client_socket;
	client_socket.connect( "127.0.0.1", 47777);

	// wait for data within the next 5s
	int bytes_recv = client_socket.timedReceive( recv_msg, 50, 5000);

	// we got a message!
	if(bytes_recv > 0)
		std::cout << "Received data from server: " << recv_msg << std::endl;

	// this is optional, we could simply do nothing here
	client_socket.disconnect();

	// if something fails, we get here
	} catch( const NET::SocketException& e)
	{
		std::cerr << e.what() << std::endl;
		return 1;
	}

	return 0;
}
<|endoftext|>


<commit_before>// Copyright (C) 2018 Elviss Strazdins
// This file is part of the Ouzel engine.

#include "Sprite.hpp"
#include "core/Setup.h"
#include "core/Engine.hpp"
#include "graphics/Renderer.hpp"
#include "Camera.hpp"
#include "SceneManager.hpp"
#include "files/FileSystem.hpp"
#include "Layer.hpp"
#include "assets/Cache.hpp"

namespace ouzel
{
    namespace scene
    {
        Sprite::Sprite():
            Component(TYPE)
        {
            whitePixelTexture = engine->getCache()->getTexture(graphics::TEXTURE_WHITE_PIXEL);

            updateCallback.callback = std::bind(&Sprite::update, this, std::placeholders::_1);

            currentAnimation = animationQueue.end();
        }

        Sprite::Sprite(const SpriteData& spriteData):
            Sprite()
        {
            init(spriteData);
        }

        Sprite::Sprite(const std::string& filename, bool mipmaps,
                       uint32_t spritesX, uint32_t spritesY,
                       const Vector2& pivot):
            Sprite()
        {
            init(filename, mipmaps, spritesX, spritesY, pivot);
        }

        Sprite::Sprite(std::shared_ptr<graphics::Texture> texture,
                       uint32_t spritesX, uint32_t spritesY,
                       const Vector2& pivot):
            Sprite()
        {
            init(texture, spritesX, spritesY, pivot);
        }

        bool Sprite::init(const SpriteData& spriteData)
        {
            material = std::make_shared<graphics::Material>();
            material->cullMode = graphics::Renderer::CullMode::NONE;
            material->blendState = spriteData.blendState ? spriteData.blendState : engine->getCache()->getBlendState(graphics::BLEND_ALPHA);
            material->shader = spriteData.shader ? spriteData.shader : engine->getCache()->getShader(graphics::SHADER_TEXTURE);
            material->textures[0] = spriteData.texture;

            animations = spriteData.animations;

            animationQueue.clear();
            animationQueue.push_back({&animations[""], false});
            currentAnimation = animationQueue.begin();

            updateBoundingBox();

            return true;
        }

        bool Sprite::init(const std::string& filename, bool mipmaps,
                          uint32_t spritesX, uint32_t spritesY,
                          const Vector2& pivot)
        {
            material = std::make_shared<graphics::Material>();
            material->cullMode = graphics::Renderer::CullMode::NONE;
            material->shader = engine->getCache()->getShader(graphics::SHADER_TEXTURE);
            material->blendState = engine->getCache()->getBlendState(graphics::BLEND_ALPHA);

            SpriteData spriteData = engine->getCache()->getSpriteData(filename, mipmaps, spritesX, spritesY, pivot);
            material->textures[0] = spriteData.texture;

            animations = spriteData.animations;

            animationQueue.clear();
            animationQueue.push_back({&animations[""], false});
            currentAnimation = animationQueue.begin();

            updateBoundingBox();

            return true;
        }

        bool Sprite::init(std::shared_ptr<graphics::Texture> newTexture,
                          uint32_t spritesX, uint32_t spritesY,
                          const Vector2& pivot)
        {
            material = std::make_shared<graphics::Material>();
            material->cullMode = graphics::Renderer::CullMode::NONE;
            material->shader = engine->getCache()->getShader(graphics::SHADER_TEXTURE);
            material->blendState = engine->getCache()->getBlendState(graphics::BLEND_ALPHA);
            material->textures[0] = newTexture;
            animations.clear();

            Size2 spriteSize = Size2(material->textures[0]->getSize().width / spritesX,
                                     material->textures[0]->getSize().height / spritesY);

            SpriteData::Animation animation;
            animation.frames.reserve(spritesX * spritesY);

            for (uint32_t x = 0; x < spritesX; ++x)
            {
                for (uint32_t y = 0; y < spritesY; ++y)
                {
                    Rect rectangle(spriteSize.width * x,
                                   spriteSize.height * y,
                                   spriteSize.width,
                                   spriteSize.height);

                    SpriteData::Frame frame = SpriteData::Frame("", newTexture->getSize(), rectangle, false, spriteSize, Vector2(), pivot);
                    animation.frames.push_back(frame);
                }
            }

            animations[""] = std::move(animation);

            animationQueue.clear();
            animationQueue.push_back({&animations[""], false});
            currentAnimation = animationQueue.begin();

            updateBoundingBox();

            return true;
        }

        void Sprite::update(float delta)
        {
            if (playing)
            {
                currentTime += delta;

                for (; currentAnimation != animationQueue.end(); ++currentAnimation)
                {
                    float length = currentAnimation->animation->frames.size() * currentAnimation->animation->frameInterval;

                    if (length > 0.0f)
                    {
                        if (length > currentTime)
                        {
                            break;
                        }
                        else
                        {
                            if (currentAnimation->repeat)
                            {
                                currentTime = fmodf(currentTime, length);

                                Event resetEvent;
                                resetEvent.type = Event::Type::ANIMATION_RESET;
                                resetEvent.animationEvent.component = this;
                                resetEvent.animationEvent.name = currentAnimation->animation->name;
                                engine->getEventDispatcher()->postEvent(resetEvent);
                                break;
                            }
                            else
                            {
                                if (running)
                                {
                                    Event finishEvent;
                                    finishEvent.type = Event::Type::ANIMATION_FINISH;
                                    finishEvent.animationEvent.component = this;
                                    finishEvent.animationEvent.name = currentAnimation->animation->name;
                                    engine->getEventDispatcher()->postEvent(finishEvent);
                                }

                                auto nextAnimation = std::next(currentAnimation);
                                if (nextAnimation == animationQueue.end())
                                {
                                    currentTime = length;
                                    running = false;
                                    break;
                                }
                                else
                                {
                                    currentTime -= length;

                                    Event startEvent;
                                    startEvent.type = Event::Type::ANIMATION_START;
                                    startEvent.animationEvent.component = this;
                                    startEvent.animationEvent.name = nextAnimation->animation->name;
                                    engine->getEventDispatcher()->postEvent(startEvent);
                                }
                            }
                        }
                    }
                }

                updateBoundingBox();
            }
        }

        void Sprite::draw(const Matrix4& transformMatrix,
                          float opacity,
                          const Matrix4& renderViewProjection,
                          const std::shared_ptr<graphics::Texture>& renderTarget,
                          const Rect& renderViewport,
                          bool depthWrite,
                          bool depthTest,
                          bool wireframe,
                          bool scissorTest,
                          const Rect& scissorRectangle)
        {
            Component::draw(transformMatrix,
                            opacity,
                            renderViewProjection,
                            renderTarget,
                            renderViewport,
                            depthWrite,
                            depthTest,
                            wireframe,
                            scissorTest,
                            scissorRectangle);

            if (currentAnimation != animationQueue.end() &&
                currentAnimation->animation->frameInterval > 0.0f)
            {
                uint32_t currentFrame = static_cast<uint32_t>(currentTime / currentAnimation->animation->frameInterval);

                if (currentFrame < currentAnimation->animation->frames.size() && material)
                {
                    Matrix4 modelViewProj = renderViewProjection * transformMatrix * offsetMatrix;
                    float colorVector[] = {material->diffuseColor.normR(), material->diffuseColor.normG(), material->diffuseColor.normB(), material->diffuseColor.normA() * opacity * material->opacity};

                    std::vector<std::vector<float>> pixelShaderConstants(1);
                    pixelShaderConstants[0] = {std::begin(colorVector), std::end(colorVector)};

                    std::vector<std::vector<float>> vertexShaderConstants(1);
                    vertexShaderConstants[0] = {std::begin(modelViewProj.m), std::end(modelViewProj.m)};

                    std::vector<std::shared_ptr<graphics::Texture>> textures;
                    if (wireframe) textures.push_back(whitePixelTexture);
                    else textures.assign(std::begin(material->textures), std::end(material->textures));

                    engine->getRenderer()->addDrawCommand(textures,
                                                                material->shader,
                                                                pixelShaderConstants,
                                                                vertexShaderConstants,
                                                                material->blendState,
                                                                currentAnimation->animation->frames[currentFrame].getMeshBuffer(),
                                                                0,
                                                                graphics::Renderer::DrawMode::TRIANGLE_LIST,
                                                                0,
                                                                renderTarget,
                                                                renderViewport,
                                                                depthWrite,
                                                                depthTest,
                                                                wireframe,
                                                                scissorTest,
                                                                scissorRectangle,
                                                                material->cullMode);
                }
            }
        }

        void Sprite::setOffset(const Vector2& newOffset)
        {
            offset = newOffset;
            Matrix4::createTranslation(offset, offsetMatrix);
            updateBoundingBox();
        }

        void Sprite::play()
        {
            if (!playing)
            {
                engine->scheduleUpdate(&updateCallback);
                playing = true;
                running = true;
            }
        }

        void Sprite::stop(bool resetAnimation)
        {
            if (playing)
            {
                playing = false;
                running = false;
                updateCallback.remove();
            }

            if (resetAnimation) reset();
        }

        void Sprite::reset()
        {
            currentTime = 0.0f;
            running = true;

            updateBoundingBox();
        }

        bool Sprite::hasAnimation(const std::string& animation) const
        {
            auto i = animations.find(animation);

            return i != animations.end();
        }

        void Sprite::setAnimation(const std::string& newAnimation, bool repeat)
        {
            animationQueue.clear();

            const SpriteData::Animation& animation = animations[newAnimation];
            animationQueue.push_back({&animation, repeat});
            currentAnimation = animationQueue.begin();
            running = true;

            updateBoundingBox();
        }

        void Sprite::addAnimation(const std::string& newAnimation, bool repeat)
        {
            const SpriteData::Animation& animation = animations[newAnimation];
            animationQueue.push_back({&animation, repeat});
            running = true;
        }

        void Sprite::setAnimationProgress(float progress)
        {
            float totalTime = 0.0f;

            for (auto i = animationQueue.begin(); i != animationQueue.end(); ++i)
            {
                totalTime += i->animation->frames.size() * i->animation->frameInterval;

                if (i->repeat) break;
            }

            setAnimationTime(totalTime * progress);
        }

        void Sprite::setAnimationTime(float time)
        {
            currentTime = time;

            for (currentAnimation = animationQueue.begin(); currentAnimation != animationQueue.end(); ++currentAnimation)
            {
                float length = currentAnimation->animation->frames.size() * currentAnimation->animation->frameInterval;

                if (length > 0.0f)
                {
                    if (length > currentTime)
                    {
                        break;
                    }
                    else
                    {
                        if (currentAnimation->repeat)
                        {
                            currentTime = fmodf(currentTime, length);
                            break;
                        }
                        else if (std::next(currentAnimation) == animationQueue.end())
                        {
                            currentTime = length;
                            break;
                        }
                        else
                        {
                            currentTime -= length;
                        }
                    }
                }
            }

            running = true;
        }

        void Sprite::updateBoundingBox()
        {
            if (currentAnimation != animationQueue.end() &&
                currentAnimation->animation->frameInterval > 0.0f)
            {
                uint32_t currentFrame = static_cast<uint32_t>(currentTime / currentAnimation->animation->frameInterval);

                if (currentFrame < currentAnimation->animation->frames.size())
                {
                    const SpriteData::Frame& frame = currentAnimation->animation->frames[currentFrame];

                    boundingBox = frame.getBoundingBox();
                    boundingBox += offset;
                }
                else
                {
                    boundingBox.reset();
                }
            }
        }
    } // namespace scene
} // namespace ouzel
<commit_msg>Show the last frame if animation progress is 100%<commit_after>// Copyright (C) 2018 Elviss Strazdins
// This file is part of the Ouzel engine.

#include "Sprite.hpp"
#include "core/Setup.h"
#include "core/Engine.hpp"
#include "graphics/Renderer.hpp"
#include "Camera.hpp"
#include "SceneManager.hpp"
#include "files/FileSystem.hpp"
#include "Layer.hpp"
#include "assets/Cache.hpp"

namespace ouzel
{
    namespace scene
    {
        Sprite::Sprite():
            Component(TYPE)
        {
            whitePixelTexture = engine->getCache()->getTexture(graphics::TEXTURE_WHITE_PIXEL);

            updateCallback.callback = std::bind(&Sprite::update, this, std::placeholders::_1);

            currentAnimation = animationQueue.end();
        }

        Sprite::Sprite(const SpriteData& spriteData):
            Sprite()
        {
            init(spriteData);
        }

        Sprite::Sprite(const std::string& filename, bool mipmaps,
                       uint32_t spritesX, uint32_t spritesY,
                       const Vector2& pivot):
            Sprite()
        {
            init(filename, mipmaps, spritesX, spritesY, pivot);
        }

        Sprite::Sprite(std::shared_ptr<graphics::Texture> texture,
                       uint32_t spritesX, uint32_t spritesY,
                       const Vector2& pivot):
            Sprite()
        {
            init(texture, spritesX, spritesY, pivot);
        }

        bool Sprite::init(const SpriteData& spriteData)
        {
            material = std::make_shared<graphics::Material>();
            material->cullMode = graphics::Renderer::CullMode::NONE;
            material->blendState = spriteData.blendState ? spriteData.blendState : engine->getCache()->getBlendState(graphics::BLEND_ALPHA);
            material->shader = spriteData.shader ? spriteData.shader : engine->getCache()->getShader(graphics::SHADER_TEXTURE);
            material->textures[0] = spriteData.texture;

            animations = spriteData.animations;

            animationQueue.clear();
            animationQueue.push_back({&animations[""], false});
            currentAnimation = animationQueue.begin();

            updateBoundingBox();

            return true;
        }

        bool Sprite::init(const std::string& filename, bool mipmaps,
                          uint32_t spritesX, uint32_t spritesY,
                          const Vector2& pivot)
        {
            material = std::make_shared<graphics::Material>();
            material->cullMode = graphics::Renderer::CullMode::NONE;
            material->shader = engine->getCache()->getShader(graphics::SHADER_TEXTURE);
            material->blendState = engine->getCache()->getBlendState(graphics::BLEND_ALPHA);

            SpriteData spriteData = engine->getCache()->getSpriteData(filename, mipmaps, spritesX, spritesY, pivot);
            material->textures[0] = spriteData.texture;

            animations = spriteData.animations;

            animationQueue.clear();
            animationQueue.push_back({&animations[""], false});
            currentAnimation = animationQueue.begin();

            updateBoundingBox();

            return true;
        }

        bool Sprite::init(std::shared_ptr<graphics::Texture> newTexture,
                          uint32_t spritesX, uint32_t spritesY,
                          const Vector2& pivot)
        {
            material = std::make_shared<graphics::Material>();
            material->cullMode = graphics::Renderer::CullMode::NONE;
            material->shader = engine->getCache()->getShader(graphics::SHADER_TEXTURE);
            material->blendState = engine->getCache()->getBlendState(graphics::BLEND_ALPHA);
            material->textures[0] = newTexture;
            animations.clear();

            Size2 spriteSize = Size2(material->textures[0]->getSize().width / spritesX,
                                     material->textures[0]->getSize().height / spritesY);

            SpriteData::Animation animation;
            animation.frames.reserve(spritesX * spritesY);

            for (uint32_t x = 0; x < spritesX; ++x)
            {
                for (uint32_t y = 0; y < spritesY; ++y)
                {
                    Rect rectangle(spriteSize.width * x,
                                   spriteSize.height * y,
                                   spriteSize.width,
                                   spriteSize.height);

                    SpriteData::Frame frame = SpriteData::Frame("", newTexture->getSize(), rectangle, false, spriteSize, Vector2(), pivot);
                    animation.frames.push_back(frame);
                }
            }

            animations[""] = std::move(animation);

            animationQueue.clear();
            animationQueue.push_back({&animations[""], false});
            currentAnimation = animationQueue.begin();

            updateBoundingBox();

            return true;
        }

        void Sprite::update(float delta)
        {
            if (playing)
            {
                currentTime += delta;

                for (; currentAnimation != animationQueue.end(); ++currentAnimation)
                {
                    float length = currentAnimation->animation->frames.size() * currentAnimation->animation->frameInterval;

                    if (length > 0.0f)
                    {
                        if (length > currentTime)
                        {
                            break;
                        }
                        else
                        {
                            if (currentAnimation->repeat)
                            {
                                currentTime = fmodf(currentTime, length);

                                Event resetEvent;
                                resetEvent.type = Event::Type::ANIMATION_RESET;
                                resetEvent.animationEvent.component = this;
                                resetEvent.animationEvent.name = currentAnimation->animation->name;
                                engine->getEventDispatcher()->postEvent(resetEvent);
                                break;
                            }
                            else
                            {
                                if (running)
                                {
                                    Event finishEvent;
                                    finishEvent.type = Event::Type::ANIMATION_FINISH;
                                    finishEvent.animationEvent.component = this;
                                    finishEvent.animationEvent.name = currentAnimation->animation->name;
                                    engine->getEventDispatcher()->postEvent(finishEvent);
                                }

                                auto nextAnimation = std::next(currentAnimation);
                                if (nextAnimation == animationQueue.end())
                                {
                                    currentTime = length;
                                    running = false;
                                    break;
                                }
                                else
                                {
                                    currentTime -= length;

                                    Event startEvent;
                                    startEvent.type = Event::Type::ANIMATION_START;
                                    startEvent.animationEvent.component = this;
                                    startEvent.animationEvent.name = nextAnimation->animation->name;
                                    engine->getEventDispatcher()->postEvent(startEvent);
                                }
                            }
                        }
                    }
                }

                updateBoundingBox();
            }
        }

        void Sprite::draw(const Matrix4& transformMatrix,
                          float opacity,
                          const Matrix4& renderViewProjection,
                          const std::shared_ptr<graphics::Texture>& renderTarget,
                          const Rect& renderViewport,
                          bool depthWrite,
                          bool depthTest,
                          bool wireframe,
                          bool scissorTest,
                          const Rect& scissorRectangle)
        {
            Component::draw(transformMatrix,
                            opacity,
                            renderViewProjection,
                            renderTarget,
                            renderViewport,
                            depthWrite,
                            depthTest,
                            wireframe,
                            scissorTest,
                            scissorRectangle);

            if (currentAnimation != animationQueue.end() &&
                currentAnimation->animation->frameInterval > 0.0f &&
                !currentAnimation->animation->frames.empty() &&
                material)
            {
                size_t currentFrame = static_cast<size_t>(currentTime / currentAnimation->animation->frameInterval);
                if (currentFrame >= currentAnimation->animation->frames.size()) currentFrame = currentAnimation->animation->frames.size() - 1;

                Matrix4 modelViewProj = renderViewProjection * transformMatrix * offsetMatrix;
                float colorVector[] = {material->diffuseColor.normR(), material->diffuseColor.normG(), material->diffuseColor.normB(), material->diffuseColor.normA() * opacity * material->opacity};

                std::vector<std::vector<float>> pixelShaderConstants(1);
                pixelShaderConstants[0] = {std::begin(colorVector), std::end(colorVector)};

                std::vector<std::vector<float>> vertexShaderConstants(1);
                vertexShaderConstants[0] = {std::begin(modelViewProj.m), std::end(modelViewProj.m)};

                std::vector<std::shared_ptr<graphics::Texture>> textures;
                if (wireframe) textures.push_back(whitePixelTexture);
                else textures.assign(std::begin(material->textures), std::end(material->textures));

                engine->getRenderer()->addDrawCommand(textures,
                                                            material->shader,
                                                            pixelShaderConstants,
                                                            vertexShaderConstants,
                                                            material->blendState,
                                                            currentAnimation->animation->frames[currentFrame].getMeshBuffer(),
                                                            0,
                                                            graphics::Renderer::DrawMode::TRIANGLE_LIST,
                                                            0,
                                                            renderTarget,
                                                            renderViewport,
                                                            depthWrite,
                                                            depthTest,
                                                            wireframe,
                                                            scissorTest,
                                                            scissorRectangle,
                                                            material->cullMode);
            }
        }

        void Sprite::setOffset(const Vector2& newOffset)
        {
            offset = newOffset;
            Matrix4::createTranslation(offset, offsetMatrix);
            updateBoundingBox();
        }

        void Sprite::play()
        {
            if (!playing)
            {
                engine->scheduleUpdate(&updateCallback);
                playing = true;
                running = true;
            }
        }

        void Sprite::stop(bool resetAnimation)
        {
            if (playing)
            {
                playing = false;
                running = false;
                updateCallback.remove();
            }

            if (resetAnimation) reset();
        }

        void Sprite::reset()
        {
            currentTime = 0.0f;
            running = true;

            updateBoundingBox();
        }

        bool Sprite::hasAnimation(const std::string& animation) const
        {
            auto i = animations.find(animation);

            return i != animations.end();
        }

        void Sprite::setAnimation(const std::string& newAnimation, bool repeat)
        {
            animationQueue.clear();

            const SpriteData::Animation& animation = animations[newAnimation];
            animationQueue.push_back({&animation, repeat});
            currentAnimation = animationQueue.begin();
            running = true;

            updateBoundingBox();
        }

        void Sprite::addAnimation(const std::string& newAnimation, bool repeat)
        {
            const SpriteData::Animation& animation = animations[newAnimation];
            animationQueue.push_back({&animation, repeat});
            running = true;
        }

        void Sprite::setAnimationProgress(float progress)
        {
            float totalTime = 0.0f;

            for (auto i = animationQueue.begin(); i != animationQueue.end(); ++i)
            {
                totalTime += i->animation->frames.size() * i->animation->frameInterval;

                if (i->repeat) break;
            }

            setAnimationTime(totalTime * progress);
        }

        void Sprite::setAnimationTime(float time)
        {
            currentTime = time;

            for (currentAnimation = animationQueue.begin(); currentAnimation != animationQueue.end(); ++currentAnimation)
            {
                float length = currentAnimation->animation->frames.size() * currentAnimation->animation->frameInterval;

                if (length > 0.0f)
                {
                    if (length > currentTime)
                    {
                        break;
                    }
                    else
                    {
                        if (currentAnimation->repeat)
                        {
                            currentTime = fmodf(currentTime, length);
                            break;
                        }
                        else if (std::next(currentAnimation) == animationQueue.end())
                        {
                            currentTime = length;
                            break;
                        }
                        else
                        {
                            currentTime -= length;
                        }
                    }
                }
            }

            running = true;
        }

        void Sprite::updateBoundingBox()
        {
            if (currentAnimation != animationQueue.end() &&
                currentAnimation->animation->frameInterval > 0.0f &&
                !currentAnimation->animation->frames.empty())
            {
                size_t currentFrame = static_cast<size_t>(currentTime / currentAnimation->animation->frameInterval);
                if (currentFrame >= currentAnimation->animation->frames.size()) currentFrame = currentAnimation->animation->frames.size() - 1;

                const SpriteData::Frame& frame = currentAnimation->animation->frames[currentFrame];

                boundingBox = frame.getBoundingBox();
                boundingBox += offset;
            }
            else
            {
                boundingBox.reset();
            }
        }
    } // namespace scene
} // namespace ouzel
<|endoftext|>


<commit_before>/*
 * File:   CCJudger.cpp
 * Author: 51isoft
 *
 * Created on 2014年8月20日, 下午3:06
 */

#include "CCJudger.h"

/**
 * Create a CodeChef Judger
 * @param _info Should be a pointer of a JudgerInfo
 */
CCJudger::CCJudger(JudgerInfo * _info) : VirtualJudger(_info) {
  language_table[CPPLANG] = "41";
  language_table[CLANG] = "11";
  language_table[JAVALANG] = "10";
  language_table[FPASLANG] = "22";
  language_table[PYLANG] = "4";
  language_table[CSLANG] = "27";
  language_table[FORTLANG] = "5";
  language_table[PERLLANG] = "3";
  language_table[RUBYLANG] = "17";
  language_table[ADALANG] = "7";
}

CCJudger::~CCJudger() {
}

void CCJudger::initHandShake(){
  socket->sendMessage(CONFIG->GetJudge_connect_string() + "\nCodeChef");
}

/**
 * Get input=hidden stuffs for login
 * @return Hidden params in string
 */
string CCJudger::getLoginHiddenParams() {
  prepareCurl();
  curl_easy_setopt(curl, CURLOPT_URL, "https://www.codechef.com/");
  performCurl();

  string html = loadAllFromFile(tmpfilename);
  string form;
  // login form
  if (!RE2::PartialMatch(html,
                         "(?s)(<form.*?user-login-form.*?</form>)",
                         &form)) {
    throw Exception("Failed to get hidden params.");
  }
  string key, value, result = "";
  // get all hidden params
  re2::StringPiece formString(form);
  while (RE2::FindAndConsume(
      &formString,
      "(?s)<input type=\"hidden\".*?name=\"(.*?)\".*?value=\"(.*?)\"", &key,
      &value)) {
    result += escapeURL(key) + "=" + escapeURL(value) + "&";
  }
  return result;
}

/**
 * Login to CodeChef
 */
void CCJudger::login() {
  string hiddenParams = getLoginHiddenParams();

  prepareCurl();
  curl_easy_setopt(curl, CURLOPT_URL,
                   "https://www.codechef.com/node?destination=node");
  string post = hiddenParams + "name=" + escapeURL(info->GetUsername()) +
      "&pass=" + escapeURL(info->GetPassword()) + "&submit.x=0&submit.y=0";
  curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post.c_str());
  performCurl();

  // check login status
  string html = loadAllFromFile(tmpfilename);
  if (html.find("<a class=\"login-link\"") != string::npos) {
    throw Exception("Login failed!");
  }
}

/**
 * Get input=hidden stuffs for submit
 * @param code  Problem code
 * @return Hidden params in pairs
 */
vector< pair<string, string> > CCJudger::getSubmitHiddenParams(string code) {
  prepareCurl();
  curl_easy_setopt(curl, CURLOPT_URL,
                   ((string) "https://www.codechef.com/submit/" + code).c_str());
  performCurl();

  string html = loadAllFromFile(tmpfilename);
  string form;
  // login form
  if (!RE2::PartialMatch(html, "(?s)(<form.*?node-form.*?</form>)", &form)) {
    throw Exception("Failed to get hidden params.");
  }
  string key, value;
  vector< pair<string, string> > result;
  // get all hidden params
  re2::StringPiece formString(form);
  while (RE2::FindAndConsume(
      &formString,
      "(?s)<input type=\"hidden\".*?name=\"(.*?)\".*?value=\"(.*?)\"",
      &key, &value)) {
    result.push_back(make_pair(key, value));
  }
  return result;
}

/**
 * Submit a run
 * @param bott      Bott file for Run info
 * @return Submit status
 */
int CCJudger::submit(Bott * bott) {
  vector< pair<string, string> > hiddenParams;
  try {
    hiddenParams = getSubmitHiddenParams(bott->Getvid());
  } catch (Exception & e) {
    // mostly because frequecy limit
    return SUBMIT_OTHER_ERROR;
  }

  // prepare form for post
  struct curl_httppost * formpost = NULL;
  struct curl_httppost * lastptr = NULL;

  for (vector< pair<string, string> >::iterator it = hiddenParams.begin();
      it != hiddenParams.end(); ++it) {
    curl_formadd(&formpost, &lastptr,
                 CURLFORM_COPYNAME, it->first.c_str(),
                 CURLFORM_COPYCONTENTS, it->second.c_str(),
                 CURLFORM_END);
  }
  curl_formadd(&formpost, &lastptr,
               CURLFORM_COPYNAME, "submission_language",
               CURLFORM_COPYCONTENTS,
                   convertLanguage(bott->Getlanguage()).c_str(),
               CURLFORM_END);
  curl_formadd(&formpost, &lastptr,
               CURLFORM_COPYNAME, "body",
               CURLFORM_COPYCONTENTS, bott->Getsrc().c_str(),
               CURLFORM_END);

  // WTF moment... CodeChef checks the filename of the uploaded file to
  // determine whether to read source from text area or uploaded file, so we
  // must upload something, otherwise it'll stop you from submitting...
  curl_formadd(&formpost, &lastptr,
               CURLFORM_COPYNAME, "files[program_file]",
               CURLFORM_FILE, "/dev/null",
               CURLFORM_FILENAME, "",
               CURLFORM_END);

  prepareCurl();
  curl_easy_setopt(
      curl, CURLOPT_URL,
      ((string) "https://www.codechef.com/submit/" + bott->Getvid()).c_str());
  curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
  performCurl();
  curl_formfree(formpost);

  // check submit status
  string html = loadAllFromFile(tmpfilename);
  if (html.find(
      "
You can\'t submit in this language for this problem!
") !=
      string::npos) {
    return SUBMIT_INVALID_LANGUAGE;
  }
  if (html.find("
") != string::npos ||
      html.find("Setremote_runid(runid);
  return VirtualJudger::SUBMIT_NORMAL;
}

/**
 * Get result and related info
 * @param bott  Original Bott info
 * @return Result Bott file
 */
Bott * CCJudger::getStatus(Bott * bott) {
  time_t begin_time = time(NULL);

  Bott * result_bott;
  while (true) {
    // check wait time
    if (time(NULL) - begin_time > info->GetMax_wait_time()) {
      throw Exception("Failed to get current result, judge time out.");
    }

    prepareCurl();
    curl_easy_setopt(
        curl, CURLOPT_URL,
        ((string) "https://www.codechef.com/get_submission_status/" +
            bott->Getremote_runid()).c_str());
    performCurl();

    string html = loadAllFromFile(tmpfilename);
    string result, time_used, memory_used;

    // get result
    if (!RE2::PartialMatch(html, "\"result_code\":\"(.*?)\"", &result)) {
      throw Exception("Failed to get current result.");
    }
    result = convertResult(result);
    if (isFinalResult(result)) {
      // if result if final, get details
      if (!RE2::PartialMatch(html,
                             "(?s)\"time\":\"(.*?)\"",
                             &time_used)) {
        throw Exception("Failed to parse details from status row.");
      }
      int time_ms = stringToDouble(time_used) * 1000 + 0.001;
      int memory_kb;
      result_bott = new Bott;
      result_bott->Settype(RESULT_REPORT);
      result_bott->Setresult(result);
      result_bott->Settime_used(time_ms);

      if (result != "Compile Error") {
        // CodeChef will update Memory usage later in submission table
        // Weird... why don't they put in get_submission_status api...
        memory_used = "0";
        prepareCurl();
        curl_easy_setopt(
            curl, CURLOPT_URL,
            ((string) "https://www.codechef.com/submissions?handle=" +
                escapeURL(info->GetUsername()) + "&pcode=" +
                escapeURL(bott->Getvid())).c_str());
        performCurl();
        html = loadAllFromFile(tmpfilename);
        string status;
        if (!RE2::PartialMatch(
            html, "(?s)(<tr class=\"kol.*?" +
                bott->Getremote_runid() + "	.*?
)", &status)) {
          // Status row is not updated in time...
          log("Memory data not ready yet... Never mind, use 0 instead.");
          memory_used = "0";
        } else if (!RE2::PartialMatch(status, ">([0-9\\.]*)M", &memory_used)) {
          memory_used = "0";
        }
        memory_kb = stringToDouble(memory_used) * 1024 + 0.001;
      }
      result_bott->Setmemory_used(memory_kb);
      result_bott->Setremote_runid(bott->Getremote_runid());
      break;
    }
  }
  return result_bott;
}

/**
 * Get compile error info from CodeChef
 * @param bott      Result bott file
 * @return Compile error info
 */
string CCJudger::getCEinfo(Bott * bott) {
  prepareCurl();
  curl_easy_setopt(curl, CURLOPT_URL,
                   ((string) "https://www.codechef.com/view/error/" +
                   bott->Getremote_runid()).c_str());
  performCurl();

  string info = loadAllFromFile(tmpfilename);
  string result;
  if (!RE2::PartialMatch(info, "(?s)
(.*)
", &result)) {
    return "";
  }

  char * ce_info = new char[info.length() + 1];
  decode_html_entities_utf8(ce_info, result.c_str());
  result = ce_info;
  delete [] ce_info;

  return result;
}

/**
 * Check whether the result is final
 * @param result        Current result
 * @return Is final one or not
 */
string CCJudger::convertResult(string result) {
  if (result.find("wait") != string::npos) return "Running";
  if (result.find("wrong") != string::npos) return "Wrong Answer";
  if (result.find("time") != string::npos) return "Time Limit Exceed";
  if (result.find("runtime") != string::npos) return "Runtime Error";
  if (result.find("compile") != string::npos) return "Compile Error";
  if (result.find("accepted") != string::npos) return "Accepted";
  return "Judge Error";
}
<commit_msg>CodeChef: fix getSubmitHiddenParams, they changed the form class<commit_after>/*
 * File:   CCJudger.cpp
 * Author: 51isoft
 *
 * Created on 2014年8月20日, 下午3:06
 */

#include "CCJudger.h"

/**
 * Create a CodeChef Judger
 * @param _info Should be a pointer of a JudgerInfo
 */
CCJudger::CCJudger(JudgerInfo * _info) : VirtualJudger(_info) {
  language_table[CPPLANG] = "41";
  language_table[CLANG] = "11";
  language_table[JAVALANG] = "10";
  language_table[FPASLANG] = "22";
  language_table[PYLANG] = "4";
  language_table[CSLANG] = "27";
  language_table[FORTLANG] = "5";
  language_table[PERLLANG] = "3";
  language_table[RUBYLANG] = "17";
  language_table[ADALANG] = "7";
}

CCJudger::~CCJudger() {
}

void CCJudger::initHandShake(){
  socket->sendMessage(CONFIG->GetJudge_connect_string() + "\nCodeChef");
}

/**
 * Get input=hidden stuffs for login
 * @return Hidden params in string
 */
string CCJudger::getLoginHiddenParams() {
  prepareCurl();
  curl_easy_setopt(curl, CURLOPT_URL, "https://www.codechef.com/");
  performCurl();

  string html = loadAllFromFile(tmpfilename);
  string form;
  // login form
  if (!RE2::PartialMatch(html,
                         "(?s)(<form.*?user-login-form.*?</form>)",
                         &form)) {
    throw Exception("Failed to get hidden params.");
  }
  string key, value, result = "";
  // get all hidden params
  re2::StringPiece formString(form);
  while (RE2::FindAndConsume(
      &formString,
      "(?s)<input type=\"hidden\".*?name=\"(.*?)\".*?value=\"(.*?)\"", &key,
      &value)) {
    result += escapeURL(key) + "=" + escapeURL(value) + "&";
  }
  return result;
}

/**
 * Login to CodeChef
 */
void CCJudger::login() {
  string hiddenParams = getLoginHiddenParams();

  prepareCurl();
  curl_easy_setopt(curl, CURLOPT_URL,
                   "https://www.codechef.com/node?destination=node");
  string post = hiddenParams + "name=" + escapeURL(info->GetUsername()) +
      "&pass=" + escapeURL(info->GetPassword()) + "&submit.x=0&submit.y=0";
  curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post.c_str());
  performCurl();

  // check login status
  string html = loadAllFromFile(tmpfilename);
  if (html.find("<a class=\"login-link\"") != string::npos) {
    throw Exception("Login failed!");
  }
}

/**
 * Get input=hidden stuffs for submit
 * @param code  Problem code
 * @return Hidden params in pairs
 */
vector< pair<string, string> > CCJudger::getSubmitHiddenParams(string code) {
  prepareCurl();
  curl_easy_setopt(curl, CURLOPT_URL,
                   ((string) "https://www.codechef.com/submit/" + code).c_str());
  performCurl();

  string html = loadAllFromFile(tmpfilename);
  string form;
  // login form
  if (!RE2::PartialMatch(html, "(?s)(<form.*?submit-form.*?</form>)", &form)) {
    throw Exception("Failed to get hidden params.");
  }
  string key, value;
  vector< pair<string, string> > result;
  // get all hidden params
  re2::StringPiece formString(form);
  while (RE2::FindAndConsume(
      &formString,
      "(?s)<input type=\"hidden\".*?name=\"(.*?)\".*?value=\"(.*?)\"",
      &key, &value)) {
    result.push_back(make_pair(key, value));
  }
  return result;
}

/**
 * Submit a run
 * @param bott      Bott file for Run info
 * @return Submit status
 */
int CCJudger::submit(Bott * bott) {
  vector< pair<string, string> > hiddenParams;
  try {
    hiddenParams = getSubmitHiddenParams(bott->Getvid());
  } catch (Exception & e) {
    // mostly because frequecy limit
    return SUBMIT_OTHER_ERROR;
  }

  // prepare form for post
  struct curl_httppost * formpost = NULL;
  struct curl_httppost * lastptr = NULL;

  for (vector< pair<string, string> >::iterator it = hiddenParams.begin();
      it != hiddenParams.end(); ++it) {
    curl_formadd(&formpost, &lastptr,
                 CURLFORM_COPYNAME, it->first.c_str(),
                 CURLFORM_COPYCONTENTS, it->second.c_str(),
                 CURLFORM_END);
  }
  curl_formadd(&formpost, &lastptr,
               CURLFORM_COPYNAME, "submission_language",
               CURLFORM_COPYCONTENTS,
                   convertLanguage(bott->Getlanguage()).c_str(),
               CURLFORM_END);
  curl_formadd(&formpost, &lastptr,
               CURLFORM_COPYNAME, "body",
               CURLFORM_COPYCONTENTS, bott->Getsrc().c_str(),
               CURLFORM_END);

  // WTF moment... CodeChef checks the filename of the uploaded file to
  // determine whether to read source from text area or uploaded file, so we
  // must upload something, otherwise it'll stop you from submitting...
  curl_formadd(&formpost, &lastptr,
               CURLFORM_COPYNAME, "files[program_file]",
               CURLFORM_FILE, "/dev/null",
               CURLFORM_FILENAME, "",
               CURLFORM_END);

  prepareCurl();
  curl_easy_setopt(
      curl, CURLOPT_URL,
      ((string) "https://www.codechef.com/submit/" + bott->Getvid()).c_str());
  curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
  performCurl();
  curl_formfree(formpost);

  // check submit status
  string html = loadAllFromFile(tmpfilename);
  if (html.find(
      "
You can\'t submit in this language for this problem!
") !=
      string::npos) {
    return SUBMIT_INVALID_LANGUAGE;
  }
  if (html.find("
") != string::npos ||
      html.find("Setremote_runid(runid);
  return VirtualJudger::SUBMIT_NORMAL;
}

/**
 * Get result and related info
 * @param bott  Original Bott info
 * @return Result Bott file
 */
Bott * CCJudger::getStatus(Bott * bott) {
  time_t begin_time = time(NULL);

  Bott * result_bott;
  while (true) {
    // check wait time
    if (time(NULL) - begin_time > info->GetMax_wait_time()) {
      throw Exception("Failed to get current result, judge time out.");
    }

    prepareCurl();
    curl_easy_setopt(
        curl, CURLOPT_URL,
        ((string) "https://www.codechef.com/get_submission_status/" +
            bott->Getremote_runid()).c_str());
    performCurl();

    string html = loadAllFromFile(tmpfilename);
    string result, time_used, memory_used;

    // get result
    if (!RE2::PartialMatch(html, "\"result_code\":\"(.*?)\"", &result)) {
      throw Exception("Failed to get current result.");
    }
    result = convertResult(result);
    if (isFinalResult(result)) {
      // if result if final, get details
      if (!RE2::PartialMatch(html,
                             "(?s)\"time\":\"(.*?)\"",
                             &time_used)) {
        throw Exception("Failed to parse details from status row.");
      }
      int time_ms = stringToDouble(time_used) * 1000 + 0.001;
      int memory_kb;
      result_bott = new Bott;
      result_bott->Settype(RESULT_REPORT);
      result_bott->Setresult(result);
      result_bott->Settime_used(time_ms);

      if (result != "Compile Error") {
        // CodeChef will update Memory usage later in submission table
        // Weird... why don't they put in get_submission_status api...
        memory_used = "0";
        prepareCurl();
        curl_easy_setopt(
            curl, CURLOPT_URL,
            ((string) "https://www.codechef.com/submissions?handle=" +
                escapeURL(info->GetUsername()) + "&pcode=" +
                escapeURL(bott->Getvid())).c_str());
        performCurl();
        html = loadAllFromFile(tmpfilename);
        string status;
        if (!RE2::PartialMatch(
            html, "(?s)(<tr class=\"kol.*?" +
                bott->Getremote_runid() + "	.*?
)", &status)) {
          // Status row is not updated in time...
          log("Memory data not ready yet... Never mind, use 0 instead.");
          memory_used = "0";
        } else if (!RE2::PartialMatch(status, ">([0-9\\.]*)M", &memory_used)) {
          memory_used = "0";
        }
        memory_kb = stringToDouble(memory_used) * 1024 + 0.001;
      }
      result_bott->Setmemory_used(memory_kb);
      result_bott->Setremote_runid(bott->Getremote_runid());
      break;
    }
  }
  return result_bott;
}

/**
 * Get compile error info from CodeChef
 * @param bott      Result bott file
 * @return Compile error info
 */
string CCJudger::getCEinfo(Bott * bott) {
  prepareCurl();
  curl_easy_setopt(curl, CURLOPT_URL,
                   ((string) "https://www.codechef.com/view/error/" +
                   bott->Getremote_runid()).c_str());
  performCurl();

  string info = loadAllFromFile(tmpfilename);
  string result;
  if (!RE2::PartialMatch(info, "(?s)
(.*)
", &result)) {
    return "";
  }

  char * ce_info = new char[info.length() + 1];
  decode_html_entities_utf8(ce_info, result.c_str());
  result = ce_info;
  delete [] ce_info;

  return result;
}

/**
 * Check whether the result is final
 * @param result        Current result
 * @return Is final one or not
 */
string CCJudger::convertResult(string result) {
  if (result.find("wait") != string::npos) return "Running";
  if (result.find("wrong") != string::npos) return "Wrong Answer";
  if (result.find("time") != string::npos) return "Time Limit Exceed";
  if (result.find("runtime") != string::npos) return "Runtime Error";
  if (result.find("compile") != string::npos) return "Compile Error";
  if (result.find("accepted") != string::npos) return "Accepted";
  return "Judge Error";
}
<|endoftext|>