<commit_before>#pragma once

#include <optional>
#include <string_view>

#include "Runtime/GCNTypes.hpp"
#include "Runtime/Character/CharacterCommon.hpp"
#include "Runtime/World/CActor.hpp"

#include <zeus/CAABox.hpp>

namespace urde {
class CScriptCoverPoint : public CActor {
  bool xe8_26_landHere : 1;
  bool xe8_27_wallHang : 1;
  bool xe8_28_stay : 1;
  bool xe8_29_ : 1;
  bool xe8_30_attackDirection : 1;
  float xec_cosHorizontalAngle;
  float xf0_sinVerticalAngle;
  float xf4_coverTime;
  bool xf8_24_crouch : 1;
  bool xf8_25_inUse : 1;
  TUniqueId xfa_occupant = kInvalidUniqueId;
  TUniqueId xfc_retreating = kInvalidUniqueId;
  std::optional<zeus::CAABox> x100_touchBounds;
  float x11c_timeLeft = 0.f;

public:
  CScriptCoverPoint(TUniqueId uid, std::string_view name, const CEntityInfo& info, zeus::CTransform xf, bool active,
                    u32 flags, bool crouch, float horizontalAngle, float verticalAngle, float coverTime);

  void Accept(IVisitor& visitor) override;
  void Think(float, CStateManager&) override;
  void AddToRenderer(const zeus::CFrustum&, CStateManager&) override {}
  void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override;
  void Render(CStateManager&) override {}
  std::optional<zeus::CAABox> GetTouchBounds() const override;
  void SetInUse(bool inUse);
  bool GetInUse(TUniqueId uid) const;
  bool ShouldLandHere() const { return xe8_26_landHere; }
  bool ShouldWallHang() const { return xe8_27_wallHang; }
  bool ShouldStay() const { return xe8_28_stay; }
  bool ShouldCrouch() const { return xf8_24_crouch; }
  bool Blown(const zeus::CVector3f& pos) const;
  float GetSinSqVerticalAngle() const;
  float GetCosHorizontalAngle() const { return xec_cosHorizontalAngle; }
  pas::ECoverDirection GetAttackDirection() const {
    return xe8_30_attackDirection ? pas::ECoverDirection::Left : pas::ECoverDirection::Right;
  }
  void Reserve(TUniqueId id) { xfa_occupant = id; }
};
} // namespace urde
<commit_msg>CScriptCoverPoint: Fix GetAttackDirection return value<commit_after>#pragma once

#include <optional>
#include <string_view>

#include "Runtime/GCNTypes.hpp"
#include "Runtime/Character/CharacterCommon.hpp"
#include "Runtime/World/CActor.hpp"

#include <zeus/CAABox.hpp>

namespace urde {
class CScriptCoverPoint : public CActor {
  bool xe8_26_landHere : 1;
  bool xe8_27_wallHang : 1;
  bool xe8_28_stay : 1;
  bool xe8_29_ : 1;
  bool xe8_30_attackDirection : 1;
  float xec_cosHorizontalAngle;
  float xf0_sinVerticalAngle;
  float xf4_coverTime;
  bool xf8_24_crouch : 1;
  bool xf8_25_inUse : 1;
  TUniqueId xfa_occupant = kInvalidUniqueId;
  TUniqueId xfc_retreating = kInvalidUniqueId;
  std::optional<zeus::CAABox> x100_touchBounds;
  float x11c_timeLeft = 0.f;

public:
  CScriptCoverPoint(TUniqueId uid, std::string_view name, const CEntityInfo& info, zeus::CTransform xf, bool active,
                    u32 flags, bool crouch, float horizontalAngle, float verticalAngle, float coverTime);

  void Accept(IVisitor& visitor) override;
  void Think(float, CStateManager&) override;
  void AddToRenderer(const zeus::CFrustum&, CStateManager&) override {}
  void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override;
  void Render(CStateManager&) override {}
  std::optional<zeus::CAABox> GetTouchBounds() const override;
  void SetInUse(bool inUse);
  bool GetInUse(TUniqueId uid) const;
  bool ShouldLandHere() const { return xe8_26_landHere; }
  bool ShouldWallHang() const { return xe8_27_wallHang; }
  bool ShouldStay() const { return xe8_28_stay; }
  bool ShouldCrouch() const { return xf8_24_crouch; }
  bool Blown(const zeus::CVector3f& pos) const;
  float GetSinSqVerticalAngle() const;
  float GetCosHorizontalAngle() const { return xec_cosHorizontalAngle; }
  pas::ECoverDirection GetAttackDirection() const {
    return xe8_30_attackDirection ? pas::ECoverDirection::Right : pas::ECoverDirection::Left;
  }
  void Reserve(TUniqueId id) { xfa_occupant = id; }
};
} // namespace urde
<|endoftext|>


<commit_before>/*
 *  Copyright 2008-2013 NVIDIA Corporation
 *
 *  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.
 */

#pragma once

#include <agency/detail/config.hpp>
#include <agency/cuda/detail/feature_test.hpp>
#include <agency/cuda/detail/terminate.hpp>
#include <agency/cuda/detail/unique_ptr.hpp>
#include <utility>

namespace agency
{
namespace cuda
{

template<typename T> class future;

template<>
class future<void>
{
  public:
    // XXX stream_ should default to per-thread default stream
    __host__ __device__
    future()
      : stream_{0}, event_{0}
    {}

    // XXX this should be private
    // XXX stream_ should default to per-thread default stream
    __host__ __device__
    future(cudaEvent_t e)
      : stream_{0}, event_{e}
    {
    } // end future()

    __host__ __device__
    future(cudaStream_t s)
      : stream_{s}
    {
#if __cuda_lib_has_cudart
      detail::throw_on_error(cudaEventCreateWithFlags(&event_, event_create_flags), "cudaEventCreateWithFlags in agency::cuda::future<void> ctor");
      detail::throw_on_error(cudaEventRecord(event_, stream_), "cudaEventRecord in agency::cuda::future<void> ctor");
#else
      detail::terminate_with_message("agency::cuda::future<void> ctor requires CUDART");
#endif // __cuda_lib_has_cudart
    } // end future()

    __host__ __device__
    future(future&& other)
      : stream_{0}, event_{0}
    {
      future::swap(stream_,      other.stream_);
      future::swap(event_,       other.event_);
    } // end future()

    __host__ __device__
    future &operator=(future&& other)
    {
      future::swap(stream_,      other.stream_);
      future::swap(event_,       other.event_);
      return *this;
    } // end operator=()

    __host__ __device__
    ~future()
    {
      if(valid())
      {
#if __cuda_lib_has_cudart
        // swallow errors
        cudaError_t e = cudaEventDestroy(event_);

#if __cuda_lib_has_printf
        if(e)
        {
          printf("CUDA error after cudaEventDestroy in agency::cuda::future<void> dtor: %s", cudaGetErrorString(e));
        } // end if
#endif // __cuda_lib_has_printf
#endif // __cuda_lib_has_cudart
      } // end if
    } // end ~future()

    __host__ __device__
    void wait() const
    {
      // XXX should probably check for valid() here

#if __cuda_lib_has_cudart

#ifndef __CUDA_ARCH__
      // XXX need to capture the error as an exception and then throw it in .get()
      detail::throw_on_error(cudaEventSynchronize(event_), "cudaEventSynchronize in agency::cuda<void>::future::wait");
#else
      // XXX need to capture the error as an exception and then throw it in .get()
      detail::throw_on_error(cudaDeviceSynchronize(), "cudaDeviceSynchronize in agency::cuda<void>::future::wait");
#endif // __CUDA_ARCH__

#else
      detail::terminate_with_message("agency::cuda::future<void>::wait() requires CUDART");
#endif // __cuda_lib_has_cudart
    } // end wait()

    __host__ __device__
    void get() const
    {
      wait();
    } // end get()

    __host__ __device__
    bool valid() const
    {
      return event_ != 0;
    } // end valid()

    __host__ __device__
    cudaEvent_t event() const
    {
      return event_;
    } // end event()

    __host__ __device__
    cudaStream_t stream() const
    {
      return stream_;
    } // end stream()

    __host__ __device__
    static future<void> make_ready()
    {
      cudaEvent_t ready_event = 0;

#if __cuda_lib_has_cudart
      detail::throw_on_error(cudaEventCreateWithFlags(&ready_event, event_create_flags), "cudaEventCreateWithFlags in agency::cuda::future<void>::make_ready");
#else
      detail::terminate_with_message("agency::cuda::future<void>::make_ready() requires CUDART");
#endif

      return future<void>{ready_event};
    }

    // XXX this is only used by grid_executor::then_execute()
    __host__ __device__
    std::nullptr_t ptr()
    {
      return nullptr;
    }

  private:
    // implement swap to avoid depending on thrust::swap
    template<class T>
    __host__ __device__
    static void swap(T& a, T& b)
    {
      T tmp{a};
      a = b;
      b = tmp;
    }

    static const int event_create_flags = cudaEventDisableTiming;

    cudaStream_t stream_;
    cudaEvent_t event_;
}; // end future<void>

template<class T>
class future
{
  public:
    __host__ __device__
    future()
      : event_()
    {}

    // XXX this should be private
    template<class U>
    __host__ __device__
    future(U&& value, future<void>& e)
      : event_(std::move(e)),
        value_(detail::make_unique<T>(event_.stream(), std::forward<U>(value)))
    {
    } // end future()

    __host__ __device__
    future(cudaStream_t s)
      : event_(s)
    {
    } // end future()

    __host__ __device__
    future(future&& other)
      : event_(std::move(other.event_)),
        value_(std::move(other.value_))
    {
    } // end future()

    __host__ __device__
    future &operator=(future&& other)
    {
      event_ = std::move(other.event_);
      value_ = std::move(other.value_);
      return *this;
    } // end operator=()

    __host__ __device__
    void wait() const
    {
      event_.wait();
    } // end wait()

    __host__ __device__
    T get() const
    {
      wait();

      return *value_;
    } // end get()

    __host__ __device__
    bool valid() const
    {
      return event_.valid();
    } // end valid()

    // XXX only used by grid_executor
    //     think of a better way to expose this
    __host__ __device__
    future<void>& void_future()
    {
      return event_;
    } // end void_future()

    template<class U>
    __host__ __device__
    static future<T> make_ready(U&& value)
    {
      auto event = future<void>::make_ready();

      return future<T>{std::forward<U>(value), event};
    }

    // XXX this is only used by grid_executor::then_execute()
    __host__ __device__
    T* ptr()
    {
      return value_.get();
    }

  private:
    future<void> event_;
    detail::unique_ptr<T> value_;
}; // end future<T>

inline __host__ __device__
future<void> make_ready_future()
{
  return future<void>::make_ready();
} // end make_ready_future()

template<class T>
inline __host__ __device__
future<typename std::decay<T>::type> make_ready_future(T&& value)
{
  return future<typename std::decay<T>::type>::make_ready(std::forward<T>(value));
} // end make_ready_future()

} // end namespace cuda
} // end namespace agency

<commit_msg>Implement cuda::future::discard_value()<commit_after>/*
 *  Copyright 2008-2013 NVIDIA Corporation
 *
 *  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.
 */

#pragma once

#include <agency/detail/config.hpp>
#include <agency/cuda/detail/feature_test.hpp>
#include <agency/cuda/detail/terminate.hpp>
#include <agency/cuda/detail/unique_ptr.hpp>
#include <utility>

namespace agency
{
namespace cuda
{

template<typename T> class future;

template<>
class future<void>
{
  public:
    // XXX stream_ should default to per-thread default stream
    __host__ __device__
    future()
      : stream_{0}, event_{0}
    {}

    // XXX this should be private
    // XXX stream_ should default to per-thread default stream
    __host__ __device__
    future(cudaEvent_t e)
      : stream_{0}, event_{e}
    {
    } // end future()

    __host__ __device__
    future(cudaStream_t s)
      : stream_{s}
    {
#if __cuda_lib_has_cudart
      detail::throw_on_error(cudaEventCreateWithFlags(&event_, event_create_flags), "cudaEventCreateWithFlags in agency::cuda::future<void> ctor");
      detail::throw_on_error(cudaEventRecord(event_, stream_), "cudaEventRecord in agency::cuda::future<void> ctor");
#else
      detail::terminate_with_message("agency::cuda::future<void> ctor requires CUDART");
#endif // __cuda_lib_has_cudart
    } // end future()

    __host__ __device__
    future(future&& other)
      : stream_{0}, event_{0}
    {
      future::swap(stream_,      other.stream_);
      future::swap(event_,       other.event_);
    } // end future()

    __host__ __device__
    future &operator=(future&& other)
    {
      future::swap(stream_,      other.stream_);
      future::swap(event_,       other.event_);
      return *this;
    } // end operator=()

    __host__ __device__
    ~future()
    {
      if(valid())
      {
#if __cuda_lib_has_cudart
        // swallow errors
        cudaError_t e = cudaEventDestroy(event_);

#if __cuda_lib_has_printf
        if(e)
        {
          printf("CUDA error after cudaEventDestroy in agency::cuda::future<void> dtor: %s", cudaGetErrorString(e));
        } // end if
#endif // __cuda_lib_has_printf
#endif // __cuda_lib_has_cudart
      } // end if
    } // end ~future()

    __host__ __device__
    void wait() const
    {
      // XXX should probably check for valid() here

#if __cuda_lib_has_cudart

#ifndef __CUDA_ARCH__
      // XXX need to capture the error as an exception and then throw it in .get()
      detail::throw_on_error(cudaEventSynchronize(event_), "cudaEventSynchronize in agency::cuda<void>::future::wait");
#else
      // XXX need to capture the error as an exception and then throw it in .get()
      detail::throw_on_error(cudaDeviceSynchronize(), "cudaDeviceSynchronize in agency::cuda<void>::future::wait");
#endif // __CUDA_ARCH__

#else
      detail::terminate_with_message("agency::cuda::future<void>::wait() requires CUDART");
#endif // __cuda_lib_has_cudart
    } // end wait()

    __host__ __device__
    void get() const
    {
      wait();
    } // end get()

    __host__ __device__
    future<void> discard_value()
    {
      return std::move(*this);
    } // end discard_value()

    __host__ __device__
    bool valid() const
    {
      return event_ != 0;
    } // end valid()

    __host__ __device__
    cudaEvent_t event() const
    {
      return event_;
    } // end event()

    __host__ __device__
    cudaStream_t stream() const
    {
      return stream_;
    } // end stream()

    __host__ __device__
    static future<void> make_ready()
    {
      cudaEvent_t ready_event = 0;

#if __cuda_lib_has_cudart
      detail::throw_on_error(cudaEventCreateWithFlags(&ready_event, event_create_flags), "cudaEventCreateWithFlags in agency::cuda::future<void>::make_ready");
#else
      detail::terminate_with_message("agency::cuda::future<void>::make_ready() requires CUDART");
#endif

      return future<void>{ready_event};
    }

    // XXX this is only used by grid_executor::then_execute()
    __host__ __device__
    std::nullptr_t ptr()
    {
      return nullptr;
    }

  private:
    // implement swap to avoid depending on thrust::swap
    template<class T>
    __host__ __device__
    static void swap(T& a, T& b)
    {
      T tmp{a};
      a = b;
      b = tmp;
    }

    static const int event_create_flags = cudaEventDisableTiming;

    cudaStream_t stream_;
    cudaEvent_t event_;
}; // end future<void>

template<class T>
class future
{
  public:
    __host__ __device__
    future()
      : event_()
    {}

    // XXX this should be private
    template<class U>
    __host__ __device__
    future(U&& value, future<void>& e)
      : event_(std::move(e)),
        value_(detail::make_unique<T>(event_.stream(), std::forward<U>(value)))
    {
    } // end future()

    __host__ __device__
    future(cudaStream_t s)
      : event_(s)
    {
    } // end future()

    __host__ __device__
    future(future&& other)
      : event_(std::move(other.event_)),
        value_(std::move(other.value_))
    {
    } // end future()

    __host__ __device__
    future &operator=(future&& other)
    {
      event_ = std::move(other.event_);
      value_ = std::move(other.value_);
      return *this;
    } // end operator=()

    __host__ __device__
    void wait() const
    {
      event_.wait();
    } // end wait()

    __host__ __device__
    T get() const
    {
      wait();

      return *value_;
    } // end get()

    __host__ __device__
    future<void> discard_value()
    {
      return std::move(event_);
    } // end discard_value()

    __host__ __device__
    bool valid() const
    {
      return event_.valid();
    } // end valid()

    // XXX only used by grid_executor
    //     think of a better way to expose this
    __host__ __device__
    future<void>& void_future()
    {
      return event_;
    } // end void_future()

    template<class U>
    __host__ __device__
    static future<T> make_ready(U&& value)
    {
      auto event = future<void>::make_ready();

      return future<T>{std::forward<U>(value), event};
    }

    // XXX this is only used by grid_executor::then_execute()
    __host__ __device__
    T* ptr()
    {
      return value_.get();
    }

  private:
    future<void> event_;
    detail::unique_ptr<T> value_;
}; // end future<T>

inline __host__ __device__
future<void> make_ready_future()
{
  return future<void>::make_ready();
} // end make_ready_future()

template<class T>
inline __host__ __device__
future<typename std::decay<T>::type> make_ready_future(T&& value)
{
  return future<typename std::decay<T>::type>::make_ready(std::forward<T>(value));
} // end make_ready_future()

} // end namespace cuda
} // end namespace agency

<|endoftext|>


<commit_before>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org

Copyright (c) 2000-2012 Torus Knot Software Ltd
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#include "SamplePlugin.h"
#include "VolumeCSG.h"

#include "OgreVolumeCSGSource.h"
#include "OgreVolumeCacheSource.h"
#include "OgreVolumeTextureSource.h"
#include "OgreVolumeMeshBuilder.h"
#include "OgreMath.h"

using namespace Ogre;
using namespace OgreBites;
using namespace Ogre::Volume;

void Sample_VolumeCSG::setupContent(void)
{
    setupControls();
    setupShaderGenerator();
    Real size = (Real)31.0;
    Vector3 to(size);

    // Light
    Light* directionalLight0 = mSceneMgr->createLight("directionalLight0");
    directionalLight0->setType(Light::LT_DIRECTIONAL);
    directionalLight0->setDirection(Vector3((Real)1, (Real)-1, (Real)1));
    directionalLight0->setDiffuseColour((Real)1, (Real)0.98, (Real)0.73);
    directionalLight0->setSpecularColour((Real)0.1, (Real)0.1, (Real)0.1);

    // Spheres
    CSGSphereSource sphere1((Real)5.0, Vector3((Real)5.5));
    CSGSphereSource sphere2((Real)5.0, Vector3((Real)25.5, (Real)5.5, (Real)5.5));
    CSGSphereSource sphere3((Real)5.0, Vector3((Real)25.5, (Real)5.5, (Real)25.5));
    CSGSphereSource sphere4((Real)5.0, Vector3((Real)5.5, (Real)5.5, (Real)25.5));

    // Cubes
    Real halfWidth = (Real)(2.5 / 2.0);
    CSGCubeSource cube1(Vector3((Real)5.5 - halfWidth), Vector3((Real)25.5 + halfWidth, (Real)5.5 + halfWidth, (Real)25.5 + halfWidth));
    CSGCubeSource cube2(Vector3((Real)5.5 + halfWidth, (Real)0.0, (Real)5.5 + halfWidth), Vector3((Real)25.5 - halfWidth, to.y, (Real)25.5 - halfWidth));
    CSGDifferenceSource difference1(&cube1, &cube2);

    // Inner rounded cube
    Real innerHalfWidth = (Real)(7.0 / 2.0);
    Vector3 center((Real)15.5, (Real)5.5, (Real)15.5);
    CSGCubeSource cube3(center - innerHalfWidth, center + innerHalfWidth);
    CSGSphereSource sphere5(innerHalfWidth + (Real)0.75, center);
    CSGIntersectionSource intersection1(&cube3, &sphere5);

    // A plane with noise
    CSGPlaneSource plane1((Real)1.0, Vector3::UNIT_Y);
    Real frequencies[] = {(Real)1.01, (Real)0.48};
    Real amplitudes[] = {(Real)0.25, (Real)0.5};
    CSGNoiseSource noise1(&plane1, frequencies, amplitudes, 2, 100);

    // Combine everything
    CSGUnionSource union1(&sphere1, &sphere2);
    CSGUnionSource union2(&union1, &sphere3);
    CSGUnionSource union3(&union2, &sphere4);
    CSGUnionSource union4(&union3, &difference1);
    CSGUnionSource union5(&union4, &intersection1);
    CSGUnionSource union6(&union5, &noise1);
    Source *src = &union6;

    mVolumeRoot = OGRE_NEW Chunk();
    SceneNode *volumeRootNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("VolumeParent");

    ChunkParameters parameters;
    parameters.sceneManager = mSceneMgr;
    parameters.src = src;
    parameters.baseError = (Real)0.25;

    mVolumeRoot->load(volumeRootNode, Vector3::ZERO, to, 1, &parameters);

    mVolumeRoot->setMaterial("Ogre/RTShader/TriplanarTexturing");

    // Camera
    mCamera->setPosition(to + (Real)7.5);
    mCamera->lookAt(center + (Real)11.0);
    mCamera->setNearClipDistance((Real)0.5);

    mRotation = (Real)0.0;

}

//-----------------------------------------------------------------------

void Sample_VolumeCSG::setupControls(void)
{
    mTrayMgr->showCursor();
#if OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS
        setDragLook(true);
#endif
    mCameraMan->setStyle(OgreBites::CS_MANUAL);
    mCameraMan->setTopSpeed((Real)25.0);
    // make room for the volume
    mTrayMgr->showLogo(TL_TOPRIGHT);
    mTrayMgr->showFrameStats(TL_TOPRIGHT);
    mTrayMgr->toggleAdvancedFrameStats();
}

//-----------------------------------------------------------------------

void Sample_VolumeCSG::setupShaderGenerator()
{
    RTShader::ShaderGenerator* mGen = RTShader::ShaderGenerator::getSingletonPtr();
    mGen->setTargetLanguage("cg");

    RTShader::RenderState* pMainRenderState =
        mGen->createOrRetrieveRenderState(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME).first;
    pMainRenderState->reset();

    mGen->invalidateScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME);

    // Make this viewport work with shader generator scheme.
    mViewport->setMaterialScheme(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME);
}

//-----------------------------------------------------------------------

void Sample_VolumeCSG::cleanupContent(void)
{
    OGRE_DELETE mVolumeRoot;
    mVolumeRoot = 0;
}

//-----------------------------------------------------------------------

Sample_VolumeCSG::Sample_VolumeCSG(void) : mVolumeRoot(0), mHideAll(false)
{
    mInfo["Title"] = "Volume CSG and RTSS triplanar texturing";
    mInfo["Description"] = "Demonstrates a volumetric CSG scene, showing sphere, cube, plane, union, difference and intersection. The triplanar texturing is generated by the RTSS.";
    mInfo["Thumbnail"] = "thumb_volumecsg.png";
    mInfo["Category"] = "Geometry";
}

//-----------------------------------------------------------------------

bool Sample_VolumeCSG::keyPressed(const OIS::KeyEvent& evt)
{
    if (evt.key == OIS::KC_H)
    {
        if (mHideAll)
        {
            mTrayMgr->showAll();
        }
        else
        {
            mTrayMgr->hideAll();
        }
        mHideAll = !mHideAll;
    }
    return SdkSample::keyPressed(evt);
}

bool Sample_VolumeCSG::frameRenderingQueued(const Ogre::FrameEvent& evt)
{
    Vector3 center((Real)15.5, (Real)5.5, (Real)15.5);
    mRotation += Radian(evt.timeSinceLastFrame * (Real)0.5);
    Real r = (Real)35.0;
    mCamera->setPosition(
        Math::Sin(mRotation) * r + center.x,
        (Real)15.0 + center.y,
        Math::Cos(mRotation) * r + center.z
    );
    mCamera->lookAt(center);
    return SdkSample::frameRenderingQueued(evt);
}

//-----------------------------------------------------------------------

void Sample_VolumeCSG::_shutdown()
{
    RTShader::RenderState* pMainRenderState =
        RTShader::ShaderGenerator::getSingleton().createOrRetrieveRenderState(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME).first;
    pMainRenderState->reset();

    SdkSample::_shutdown();
}

//-----------------------------------------------------------------------

#ifndef OGRE_STATIC_LIB

SamplePlugin* sp;
Sample* s;

//-----------------------------------------------------------------------

extern "C" _OgreSampleExport void dllStartPlugin()
{
    s = new Sample_VolumeCSG();
    sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample");
    sp->addSample(s);
    Root::getSingleton().installPlugin(sp);
}

//-----------------------------------------------------------------------

extern "C" _OgreSampleExport void dllStopPlugin()
{
    Root::getSingleton().uninstallPlugin(sp);
    OGRE_DELETE sp;
    delete s;
}

#endif
<commit_msg>Backout changeset 91b796f879aba6fc030b36895769ae1ef5d7c856<commit_after>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org

Copyright (c) 2000-2012 Torus Knot Software Ltd
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#include "SamplePlugin.h"
#include "VolumeCSG.h"

#include "OgreVolumeCSGSource.h"
#include "OgreVolumeCacheSource.h"
#include "OgreVolumeTextureSource.h"
#include "OgreVolumeMeshBuilder.h"
#include "OgreMath.h"

using namespace Ogre;
using namespace OgreBites;
using namespace Ogre::Volume;

void Sample_VolumeCSG::setupContent(void)
{
    setupControls();
    setupShaderGenerator();
    Real size = (Real)31.0;
    Vector3 to(size);

    // Light
    Light* directionalLight0 = mSceneMgr->createLight("directionalLight0");
    directionalLight0->setType(Light::LT_DIRECTIONAL);
    directionalLight0->setDirection(Vector3((Real)1, (Real)-1, (Real)1));
    directionalLight0->setDiffuseColour((Real)1, (Real)0.98, (Real)0.73);
    directionalLight0->setSpecularColour((Real)0.1, (Real)0.1, (Real)0.1);

    // Spheres
    CSGSphereSource sphere1((Real)5.0, Vector3((Real)5.5));
    CSGSphereSource sphere2((Real)5.0, Vector3((Real)25.5, (Real)5.5, (Real)5.5));
    CSGSphereSource sphere3((Real)5.0, Vector3((Real)25.5, (Real)5.5, (Real)25.5));
    CSGSphereSource sphere4((Real)5.0, Vector3((Real)5.5, (Real)5.5, (Real)25.5));

    // Cubes
    Real halfWidth = (Real)(2.5 / 2.0);
    CSGCubeSource cube1(Vector3((Real)5.5 - halfWidth), Vector3((Real)25.5 + halfWidth, (Real)5.5 + halfWidth, (Real)25.5 + halfWidth));
    CSGCubeSource cube2(Vector3((Real)5.5 + halfWidth, (Real)0.0, (Real)5.5 + halfWidth), Vector3((Real)25.5 - halfWidth, to.y, (Real)25.5 - halfWidth));
    CSGDifferenceSource difference1(&cube1, &cube2);

    // Inner rounded cube
    Real innerHalfWidth = (Real)(7.0 / 2.0);
    Vector3 center((Real)15.5, (Real)5.5, (Real)15.5);
    CSGCubeSource cube3(center - innerHalfWidth, center + innerHalfWidth);
    CSGSphereSource sphere5(innerHalfWidth + (Real)0.75, center);
    CSGIntersectionSource intersection1(&cube3, &sphere5);

    // A plane with noise
    CSGPlaneSource plane1((Real)1.0, Vector3::UNIT_Y);
    Real frequencies[] = {(Real)1.01, (Real)0.48};
    Real amplitudes[] = {(Real)0.25, (Real)0.5};
    CSGNoiseSource noise1(&plane1, frequencies, amplitudes, 2, 100);

    // Combine everything
    CSGUnionSource union1(&sphere1, &sphere2);
    CSGUnionSource union2(&union1, &sphere3);
    CSGUnionSource union3(&union2, &sphere4);
    CSGUnionSource union4(&union3, &difference1);
    CSGUnionSource union5(&union4, &intersection1);
    CSGUnionSource union6(&union5, &noise1);
    Source *src = &union6;

    src->serialize(Vector3::ZERO, to, (Real)0.12109375, "volume.dat");

    mVolumeRoot = OGRE_NEW Chunk();
    SceneNode *volumeRootNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("VolumeParent");

    ChunkParameters parameters;
    parameters.sceneManager = mSceneMgr;
    parameters.src = src;
    parameters.baseError = (Real)0.25;

    mVolumeRoot->load(volumeRootNode, Vector3::ZERO, to, 1, &parameters);

    mVolumeRoot->setMaterial("Ogre/RTShader/TriplanarTexturing");

    // Camera
    mCamera->setPosition(to + (Real)7.5);
    mCamera->lookAt(center + (Real)11.0);
    mCamera->setNearClipDistance((Real)0.5);

    mRotation = (Real)0.0;

}

//-----------------------------------------------------------------------

void Sample_VolumeCSG::setupControls(void)
{
    mTrayMgr->showCursor();
#if OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS
        setDragLook(true);
#endif
    mCameraMan->setStyle(OgreBites::CS_MANUAL);
    mCameraMan->setTopSpeed((Real)25.0);
    // make room for the volume
    mTrayMgr->showLogo(TL_TOPRIGHT);
    mTrayMgr->showFrameStats(TL_TOPRIGHT);
    mTrayMgr->toggleAdvancedFrameStats();
}

//-----------------------------------------------------------------------

void Sample_VolumeCSG::setupShaderGenerator()
{
    RTShader::ShaderGenerator* mGen = RTShader::ShaderGenerator::getSingletonPtr();
    mGen->setTargetLanguage("cg");

    RTShader::RenderState* pMainRenderState =
        mGen->createOrRetrieveRenderState(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME).first;
    pMainRenderState->reset();

    mGen->invalidateScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME);

    // Make this viewport work with shader generator scheme.
    mViewport->setMaterialScheme(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME);
}

//-----------------------------------------------------------------------

void Sample_VolumeCSG::cleanupContent(void)
{
    OGRE_DELETE mVolumeRoot;
    mVolumeRoot = 0;
}

//-----------------------------------------------------------------------

Sample_VolumeCSG::Sample_VolumeCSG(void) : mVolumeRoot(0), mHideAll(false)
{
    mInfo["Title"] = "Volume CSG and RTSS triplanar texturing";
    mInfo["Description"] = "Demonstrates a volumetric CSG scene, showing sphere, cube, plane, union, difference and intersection. The triplanar texturing is generated by the RTSS.";
    mInfo["Thumbnail"] = "thumb_volumecsg.png";
    mInfo["Category"] = "Geometry";
}

//-----------------------------------------------------------------------

bool Sample_VolumeCSG::keyPressed(const OIS::KeyEvent& evt)
{
    if (evt.key == OIS::KC_H)
    {
        if (mHideAll)
        {
            mTrayMgr->showAll();
        }
        else
        {
            mTrayMgr->hideAll();
        }
        mHideAll = !mHideAll;
    }
    return SdkSample::keyPressed(evt);
}

bool Sample_VolumeCSG::frameRenderingQueued(const Ogre::FrameEvent& evt)
{
    Vector3 center((Real)15.5, (Real)5.5, (Real)15.5);
    mRotation += Radian(evt.timeSinceLastFrame * (Real)0.5);
    Real r = (Real)35.0;
    mCamera->setPosition(
        Math::Sin(mRotation) * r + center.x,
        (Real)15.0 + center.y,
        Math::Cos(mRotation) * r + center.z
    );
    mCamera->lookAt(center);
    return SdkSample::frameRenderingQueued(evt);
}

//-----------------------------------------------------------------------

void Sample_VolumeCSG::_shutdown()
{
    RTShader::RenderState* pMainRenderState =
        RTShader::ShaderGenerator::getSingleton().createOrRetrieveRenderState(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME).first;
    pMainRenderState->reset();

    SdkSample::_shutdown();
}

//-----------------------------------------------------------------------

#ifndef OGRE_STATIC_LIB

SamplePlugin* sp;
Sample* s;

//-----------------------------------------------------------------------

extern "C" _OgreSampleExport void dllStartPlugin()
{
    s = new Sample_VolumeCSG();
    sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample");
    sp->addSample(s);
    Root::getSingleton().installPlugin(sp);
}

//-----------------------------------------------------------------------

extern "C" _OgreSampleExport void dllStopPlugin()
{
    Root::getSingleton().uninstallPlugin(sp);
    OGRE_DELETE sp;
    delete s;
}

#endif
<|endoftext|>


<commit_before>/*  Copyright (c) MediaArea.net SARL. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license that can
 *  be found in the License.html file in the root of the source tree.
 */

//---------------------------------------------------------------------------
// Pre-compilation
#include "MediaInfo/PreComp.h"
#ifdef __BORLANDC__
    #pragma hdrstop
#endif
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
#include "MediaInfo/Setup.h"
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
#if defined(MEDIAINFO_TTML_YES)
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
#include "MediaInfo/Text/File_Ttml.h"
#if MEDIAINFO_EVENTS
    #include "MediaInfo/MediaInfo_Config_MediaInfo.h"
    #include "MediaInfo/MediaInfo_Events_Internal.h"
#endif //MEDIAINFO_EVENTS
#include "tinyxml2.h"
#include <cstring>
using namespace tinyxml2;
using namespace std;
//---------------------------------------------------------------------------

namespace MediaInfoLib
{

//***************************************************************************
// Utils
//***************************************************************************

int64u Ttml_str2timecode(const char* Value)
{
    size_t Length=strlen(Value);
         if (Length>=8
     && Value[0]>='0' && Value[0]<='9'
     && Value[1]>='0' && Value[1]<='9'
     && Value[2]==':'
     && Value[3]>='0' && Value[3]<='9'
     && Value[4]>='0' && Value[4]<='9'
     && Value[5]==':'
     && Value[6]>='0' && Value[6]<='9'
     && Value[7]>='0' && Value[7]<='9')
    {
        int64u ToReturn=(int64u)(Value[0]-'0')*10*60*60*1000000000
                       +(int64u)(Value[1]-'0')   *60*60*1000000000
                       +(int64u)(Value[3]-'0')   *10*60*1000000000
                       +(int64u)(Value[4]-'0')      *60*1000000000
                       +(int64u)(Value[6]-'0')      *10*1000000000
                       +(int64u)(Value[7]-'0')         *1000000000;
        if (Length>=9 && (Value[8]=='.' || Value[8]==','))
        {
            if (Length>9+9)
                Length=9+9; //Nanoseconds max
            const char* Value_End=Value+Length;
            Value+=9;
            int64u Multiplier=100000000;
            while (Value<Value_End)
            {
                ToReturn+=(int64u)(*Value-'0')*Multiplier;
                Multiplier/=10;
                Value++;
            }
        }

        return ToReturn;
    }
    else if (Length>=2
     && Value[Length-1]=='s')
    {
        return (int64u)(atof(Value)*1000000000);
    }
    else
        return (int64u)-1;
}

//***************************************************************************
// Constructor/Destructor
//***************************************************************************

//---------------------------------------------------------------------------
File_Ttml::File_Ttml()
:File__Analyze()
{
    //Configuration
    #if MEDIAINFO_EVENTS
        ParserIDs[0]=MediaInfo_Parser_Ttml;
        StreamIDs_Width[0]=0;
    #endif //MEDIAINFO_EVENTS

    //Init
    Frame_Count=0;
}

//***************************************************************************
// Streams management
//***************************************************************************

//---------------------------------------------------------------------------
void File_Ttml::Streams_Accept()
{
    Fill(Stream_General, 0, General_Format, "TTML");

    Stream_Prepare(Stream_Text);
    Fill(Stream_Text, 0, "Format", "TTML");
}

//***************************************************************************
// Buffer - Global
//***************************************************************************

//---------------------------------------------------------------------------
void File_Ttml::Read_Buffer_Unsynched()
{
    GoTo(0);
}

//---------------------------------------------------------------------------
#if MEDIAINFO_SEEK
size_t File_Ttml::Read_Buffer_Seek (size_t Method, int64u Value, int64u ID)
{
    Open_Buffer_Unsynch();
    return 1;
}
#endif //MEDIAINFO_SEEK

//***************************************************************************
// Buffer - File header
//***************************************************************************

//---------------------------------------------------------------------------
bool File_Ttml::FileHeader_Begin()
{
    //All should be OK...
    return true;
}

//---------------------------------------------------------------------------
void File_Ttml::Read_Buffer_Continue()
{
    tinyxml2::XMLDocument document;

    if (!FileHeader_Begin_XML(document))
        return;

    XMLElement* Root=document.FirstChildElement("tt");
    if (!Root)
    {
        Reject();
        return;
    }

    if (!Status[IsAccepted])
    {
        Accept();

        #if MEDIAINFO_EVENTS
            MuxingMode=(int8u)-1;
            if (StreamIDs_Size>=2 && ParserIDs[StreamIDs_Size-2]==MediaInfo_Parser_Mpeg4)
                MuxingMode=11; //MPEG-4
            if (StreamIDs_Size>2 && ParserIDs[StreamIDs_Size-2]==MediaInfo_Parser_Mxf) //Only if referenced MXF
                MuxingMode=13; //MXF
        #endif MEDIAINFO_EVENTS
    }

    tinyxml2::XMLElement*       div=NULL;
    #if MEDIAINFO_EVENTS
    tinyxml2::XMLElement*       p=NULL;
    #endif //MEDIAINFO_EVENTS
    for (XMLElement* tt_element=Root->FirstChildElement(); tt_element; tt_element=tt_element->NextSiblingElement())
    {
        //body
        if (!strcmp(tt_element->Value(), "body"))
        {
            for (XMLElement* body_element=tt_element->FirstChildElement(); body_element; body_element=body_element->NextSiblingElement())
            {
                //div
                if (!strcmp(body_element->Value(), "div"))
                {
                    for (XMLElement* div_element=body_element->FirstChildElement(); div_element; div_element=div_element->NextSiblingElement())
                    {
                        //p
                        if (!strcmp(div_element->Value(), "p"))
                        {
                            div=body_element;
                            #if MEDIAINFO_EVENTS
                                p=div_element;
                            #endif //MEDIAINFO_EVENTS
                            break;
                        }
                    }

                    if (div)
                        break;
                }
            }

            if (div)
                break;
        }
    }

    #if MEDIAINFO_DEMUX
        Demux(Buffer, Buffer_Size, ContentType_MainStream);
    #endif //MEDIAINFO_DEMUX

    // Output
    #if MEDIAINFO_EVENTS
        for (; p; p=p->NextSiblingElement())
        {
            //p
            if (!strcmp(p->Value(), "p"))
            {
                const char* Attribute;

                int64u DTS_Begin=(int64u)-1;
                Attribute=p->Attribute("begin");
                if (Attribute)
                    DTS_Begin=Ttml_str2timecode(Attribute);
                int64u DTS_End=(int64u)-1;
                Attribute=p->Attribute("end");
                if (Attribute)
                    DTS_End=Ttml_str2timecode(Attribute);
                string ContentUtf8;
                XMLPrinter printer;
                p->Accept(&printer);
                ContentUtf8+=printer.CStr();
                while (!ContentUtf8.empty() && (ContentUtf8[ContentUtf8.size()-1]=='\r' || ContentUtf8[ContentUtf8.size()-1]=='\n'))
                    ContentUtf8.resize(ContentUtf8.size()-1);
                Ztring Content; if (p->FirstChild()) Content.From_UTF8(p->FirstChild()->Value());
                Frame_Count++;
            }
        }
    #endif MEDIAINFO_EVENTS

    Buffer_Offset=Buffer_Size;
}

} //NameSpace

#endif //MEDIAINFO_TTML_YES
<commit_msg>x TTML demux was done too early with NextPacket interface<commit_after>/*  Copyright (c) MediaArea.net SARL. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license that can
 *  be found in the License.html file in the root of the source tree.
 */

//---------------------------------------------------------------------------
// Pre-compilation
#include "MediaInfo/PreComp.h"
#ifdef __BORLANDC__
    #pragma hdrstop
#endif
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
#include "MediaInfo/Setup.h"
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
#if defined(MEDIAINFO_TTML_YES)
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
#include "MediaInfo/Text/File_Ttml.h"
#if MEDIAINFO_EVENTS
    #include "MediaInfo/MediaInfo_Config_MediaInfo.h"
    #include "MediaInfo/MediaInfo_Events_Internal.h"
#endif //MEDIAINFO_EVENTS
#include "tinyxml2.h"
#include <cstring>
using namespace tinyxml2;
using namespace std;
//---------------------------------------------------------------------------

namespace MediaInfoLib
{

//***************************************************************************
// Utils
//***************************************************************************

int64u Ttml_str2timecode(const char* Value)
{
    size_t Length=strlen(Value);
         if (Length>=8
     && Value[0]>='0' && Value[0]<='9'
     && Value[1]>='0' && Value[1]<='9'
     && Value[2]==':'
     && Value[3]>='0' && Value[3]<='9'
     && Value[4]>='0' && Value[4]<='9'
     && Value[5]==':'
     && Value[6]>='0' && Value[6]<='9'
     && Value[7]>='0' && Value[7]<='9')
    {
        int64u ToReturn=(int64u)(Value[0]-'0')*10*60*60*1000000000
                       +(int64u)(Value[1]-'0')   *60*60*1000000000
                       +(int64u)(Value[3]-'0')   *10*60*1000000000
                       +(int64u)(Value[4]-'0')      *60*1000000000
                       +(int64u)(Value[6]-'0')      *10*1000000000
                       +(int64u)(Value[7]-'0')         *1000000000;
        if (Length>=9 && (Value[8]=='.' || Value[8]==','))
        {
            if (Length>9+9)
                Length=9+9; //Nanoseconds max
            const char* Value_End=Value+Length;
            Value+=9;
            int64u Multiplier=100000000;
            while (Value<Value_End)
            {
                ToReturn+=(int64u)(*Value-'0')*Multiplier;
                Multiplier/=10;
                Value++;
            }
        }

        return ToReturn;
    }
    else if (Length>=2
     && Value[Length-1]=='s')
    {
        return (int64u)(atof(Value)*1000000000);
    }
    else
        return (int64u)-1;
}

//***************************************************************************
// Constructor/Destructor
//***************************************************************************

//---------------------------------------------------------------------------
File_Ttml::File_Ttml()
:File__Analyze()
{
    //Configuration
    #if MEDIAINFO_EVENTS
        ParserIDs[0]=MediaInfo_Parser_Ttml;
        StreamIDs_Width[0]=0;
    #endif //MEDIAINFO_EVENTS

    //Init
    Frame_Count=0;
}

//***************************************************************************
// Streams management
//***************************************************************************

//---------------------------------------------------------------------------
void File_Ttml::Streams_Accept()
{
    Fill(Stream_General, 0, General_Format, "TTML");

    Stream_Prepare(Stream_Text);
    Fill(Stream_Text, 0, "Format", "TTML");
}

//***************************************************************************
// Buffer - Global
//***************************************************************************

//---------------------------------------------------------------------------
void File_Ttml::Read_Buffer_Unsynched()
{
    GoTo(0);
}

//---------------------------------------------------------------------------
#if MEDIAINFO_SEEK
size_t File_Ttml::Read_Buffer_Seek (size_t Method, int64u Value, int64u ID)
{
    Open_Buffer_Unsynch();
    return 1;
}
#endif //MEDIAINFO_SEEK

//***************************************************************************
// Buffer - File header
//***************************************************************************

//---------------------------------------------------------------------------
bool File_Ttml::FileHeader_Begin()
{
    //All should be OK...
    return true;
}

//---------------------------------------------------------------------------
void File_Ttml::Read_Buffer_Continue()
{
    tinyxml2::XMLDocument document;

    if (!FileHeader_Begin_XML(document))
        return;

    XMLElement* Root=document.FirstChildElement("tt");
    if (!Root)
    {
        Reject();
        return;
    }

    if (!Status[IsAccepted])
    {
        Accept();

        #if MEDIAINFO_EVENTS
            MuxingMode=(int8u)-1;
            if (StreamIDs_Size>=2 && ParserIDs[StreamIDs_Size-2]==MediaInfo_Parser_Mpeg4)
                MuxingMode=11; //MPEG-4
            if (StreamIDs_Size>2 && ParserIDs[StreamIDs_Size-2]==MediaInfo_Parser_Mxf) //Only if referenced MXF
                MuxingMode=13; //MXF
        #endif MEDIAINFO_EVENTS

        #if MEDIAINFO_DEMUX && MEDIAINFO_NEXTPACKET
            if (Config->NextPacket_Get() && Config->Event_CallBackFunction_IsSet())
                return; // Waiting for NextPacket
        #endif //MEDIAINFO_DEMUX && MEDIAINFO_NEXTPACKET
    }

    tinyxml2::XMLElement*       div=NULL;
    #if MEDIAINFO_EVENTS
    tinyxml2::XMLElement*       p=NULL;
    #endif //MEDIAINFO_EVENTS
    for (XMLElement* tt_element=Root->FirstChildElement(); tt_element; tt_element=tt_element->NextSiblingElement())
    {
        //body
        if (!strcmp(tt_element->Value(), "body"))
        {
            for (XMLElement* body_element=tt_element->FirstChildElement(); body_element; body_element=body_element->NextSiblingElement())
            {
                //div
                if (!strcmp(body_element->Value(), "div"))
                {
                    for (XMLElement* div_element=body_element->FirstChildElement(); div_element; div_element=div_element->NextSiblingElement())
                    {
                        //p
                        if (!strcmp(div_element->Value(), "p"))
                        {
                            div=body_element;
                            #if MEDIAINFO_EVENTS
                                p=div_element;
                            #endif //MEDIAINFO_EVENTS
                            break;
                        }
                    }

                    if (div)
                        break;
                }
            }

            if (div)
                break;
        }
    }

    #if MEDIAINFO_DEMUX
        Demux(Buffer, Buffer_Size, ContentType_MainStream);
    #endif //MEDIAINFO_DEMUX

    // Output
    #if MEDIAINFO_EVENTS
        for (; p; p=p->NextSiblingElement())
        {
            //p
            if (!strcmp(p->Value(), "p"))
            {
                const char* Attribute;

                int64u DTS_Begin=(int64u)-1;
                Attribute=p->Attribute("begin");
                if (Attribute)
                    DTS_Begin=Ttml_str2timecode(Attribute);
                int64u DTS_End=(int64u)-1;
                Attribute=p->Attribute("end");
                if (Attribute)
                    DTS_End=Ttml_str2timecode(Attribute);
                string ContentUtf8;
                XMLPrinter printer;
                p->Accept(&printer);
                ContentUtf8+=printer.CStr();
                while (!ContentUtf8.empty() && (ContentUtf8[ContentUtf8.size()-1]=='\r' || ContentUtf8[ContentUtf8.size()-1]=='\n'))
                    ContentUtf8.resize(ContentUtf8.size()-1);
                Ztring Content; if (p->FirstChild()) Content.From_UTF8(p->FirstChild()->Value());
                Frame_Count++;
            }
        }
    #endif MEDIAINFO_EVENTS

    Buffer_Offset=Buffer_Size;
}

} //NameSpace

#endif //MEDIAINFO_TTML_YES
<|endoftext|>


<commit_before>#include <event/event_callback.h>
#include <event/event_main.h>
#include <event/event_system.h>

#define	TIMER_MS	1000

static uint8_t zbuf[8192];

class BufferSpeed {
	uintmax_t bytes_;
	Action *callback_action_;
	Action *timeout_action_;
public:
	BufferSpeed(void)
	: callback_action_(NULL),
	  timeout_action_(NULL)
	{
		callback_action_ = callback(this, &BufferSpeed::callback_complete)->schedule();

		INFO("/example/buffer/append/speed1") << "Arming timer.";
		timeout_action_ = EventSystem::instance()->timeout(TIMER_MS, callback(this, &BufferSpeed::timer));
	}

	~BufferSpeed()
	{
		ASSERT(timeout_action_ == NULL);
	}

private:
	void callback_complete(void)
	{
		callback_action_->cancel();
		callback_action_ = NULL;

		Buffer tmp;
		tmp.append(zbuf, sizeof zbuf);
		bytes_ += tmp.length();

		callback_action_ = callback(this, &BufferSpeed::callback_complete)->schedule();
	}

	void timer(void)
	{
		timeout_action_->cancel();
		timeout_action_ = NULL;

		ASSERT(callback_action_ != NULL);
		callback_action_->cancel();
		callback_action_ = NULL;

		INFO("/example/buffer/append/speed1") << "Timer expired; " << bytes_ << " bytes appended.";
	}
};

int
main(void)
{
	INFO("/example/buffer/append/speed1") << "Timer delay: " << TIMER_MS << "ms";

	memset(zbuf, 0, sizeof zbuf);

	BufferSpeed *cs = new BufferSpeed();

	event_main();

	delete cs;
}
<commit_msg>Initialize the byte counter.<commit_after>#include <event/event_callback.h>
#include <event/event_main.h>
#include <event/event_system.h>

#define	TIMER_MS	1000

static uint8_t zbuf[8192];

class BufferSpeed {
	uintmax_t bytes_;
	Action *callback_action_;
	Action *timeout_action_;
public:
	BufferSpeed(void)
	: bytes_(0),
	  callback_action_(NULL),
	  timeout_action_(NULL)
	{
		callback_action_ = callback(this, &BufferSpeed::callback_complete)->schedule();

		INFO("/example/buffer/append/speed1") << "Arming timer.";
		timeout_action_ = EventSystem::instance()->timeout(TIMER_MS, callback(this, &BufferSpeed::timer));
	}

	~BufferSpeed()
	{
		ASSERT(timeout_action_ == NULL);
	}

private:
	void callback_complete(void)
	{
		callback_action_->cancel();
		callback_action_ = NULL;

		Buffer tmp;
		tmp.append(zbuf, sizeof zbuf);
		bytes_ += tmp.length();

		callback_action_ = callback(this, &BufferSpeed::callback_complete)->schedule();
	}

	void timer(void)
	{
		timeout_action_->cancel();
		timeout_action_ = NULL;

		ASSERT(callback_action_ != NULL);
		callback_action_->cancel();
		callback_action_ = NULL;

		INFO("/example/buffer/append/speed1") << "Timer expired; " << bytes_ << " bytes appended.";
	}
};

int
main(void)
{
	INFO("/example/buffer/append/speed1") << "Timer delay: " << TIMER_MS << "ms";

	memset(zbuf, 0, sizeof zbuf);

	BufferSpeed *cs = new BufferSpeed();

	event_main();

	delete cs;
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    $RCSfile: antsCommandLineParser.cxx,v $
  Language:  C++
  Date:      $Date: 2009/01/22 22:43:11 $
  Version:   $Revision: 1.1 $

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "antsCommandLineParser.h"

#include <algorithm>

namespace itk
{
namespace ants
{
CommandLineParser
::CommandLineParser()
{
  this->m_Options.clear();
  this->m_Command.clear();
  this->m_CommandDescription.clear();
  this->m_UnknownOptions.clear();

  this->m_LeftDelimiter = '[';
  this->m_RightDelimiter = ']';
}

void
CommandLineParser
::AddOption( OptionType::Pointer option )
{
  if( ( option->GetShortName() != '\0' ||
        !this->GetOption( option->GetShortName() ) )
      || ( !option->GetLongName().empty() ||
           !this->GetOption( option->GetLongName() ) ) )
    {
    this->m_Options.push_back( option );
    }
  else
    {
    if( option->GetShortName() != '\0' &&
        this->GetOption( option->GetShortName() ) )
      {
      itkWarningMacro( "Duplicate short option '-"
                       << option->GetShortName() << "'" );
      }
    if( !( option->GetLongName().empty() ) &&
        this->GetOption( option->GetLongName() ) )
      {
      itkWarningMacro( "Duplicate long option '--"
                       << option->GetLongName() << "'" );
      }
    }
}

void
CommandLineParser
::Parse( unsigned int argc, char * *argv )
{
  std::vector<std::string> arguments =
    this->RegroupCommandLineArguments( argc, argv );

  unsigned int n = 0;

  this->m_Command = arguments[n++];

  while( n < arguments.size() )
    {
    std::string argument = arguments[n++];
    std::string name;

    name.clear();
    if( argument.find( "--" ) == 0 )
      {
      name = argument.substr( 2, argument.length() - 1 );
      }
    else if( argument.find( "-" ) == 0 && argument.find( "--" ) > 0 )
      {
      name = argument.substr( 1, 2 );
      }

    if( !( name.empty() ) )
      {
      OptionType::Pointer option = this->GetOption( name );
      if( !option )
        {
        OptionType::Pointer unknownOption = OptionType::New();
        if( name.length() > 1 )
          {
          unknownOption->SetLongName( name );
          }
        else
          {
          unknownOption->SetShortName( name.at( 0 ) );
          }
        if( n == arguments.size() )
          {
          unknownOption->AddValue( "1",
                                   this->m_LeftDelimiter, this->m_RightDelimiter );
          }
        else
          {
          for( unsigned int m = n; m < arguments.size(); m++ )
            {
            std::string value = arguments[m];
            if( value.find( "-" ) != 0 )
              {
              unknownOption->AddValue( value,
                                       this->m_LeftDelimiter, this->m_RightDelimiter );
              }
            else
              {
              if( m == n )
                {
                unknownOption->AddValue( "1",
                                         this->m_LeftDelimiter, this->m_RightDelimiter );
                }
              n = m;
              break;
              }
            }
          }
        this->m_UnknownOptions.push_back( unknownOption );
        }
      else  // the option exists
        {
        if( n == arguments.size() )
          {
          option->AddValue( "1",
                            this->m_LeftDelimiter, this->m_RightDelimiter );
          }
        else
          {
          for( unsigned int m = n; m < arguments.size(); m++ )
            {
            std::string value = arguments[m];
            if( value.find( "-" ) != 0 )
              {
              option->AddValue( value,
                                this->m_LeftDelimiter, this->m_RightDelimiter );
              }
            else
              {
              if( m == n )
                {
                option->AddValue( "1",
                                  this->m_LeftDelimiter, this->m_RightDelimiter );
                }
              n = m;
              break;
              }
            }
          }
        }
      }
    }
}

std::vector<std::string>
CommandLineParser
::RegroupCommandLineArguments( unsigned int argc, char * *argv )
{
  /**
   * Inclusion of this function allows the user to use spaces inside
   * the left and right delimiters.  Also replace other left and right
   * delimiters.
   */
  std::vector<std::string> arguments;

  std::string currentArg( "" );
  bool        isArgOpen = false;

  for( unsigned int n = 0; n < argc; n++ )
    {
    std::string a( argv[n] );

    // replace left delimiters
    std::replace( a.begin(), a.end(), '{', '[' );
    std::replace( a.begin(), a.end(), '(', '[' );
    std::replace( a.begin(), a.end(), '<', '[' );

    // replace right delimiters
    std::replace( a.begin(), a.end(), '}', ']' );
    std::replace( a.begin(), a.end(), ')', ']' );
    std::replace( a.begin(), a.end(), '>', ']' );

    if( isArgOpen )
      {
      std::size_t leftDelimiterPosition = a.find( this->m_LeftDelimiter );
      if( leftDelimiterPosition != std::string::npos )
        {
        itkExceptionMacro( "Incorrect command line specification." );
        }

      std::size_t rightDelimiterPosition = a.find( this->m_RightDelimiter );
      if( rightDelimiterPosition != std::string::npos )
        {
        if( rightDelimiterPosition < a.length() - 1 )
          {
          itkExceptionMacro( "Incorrect command line specification." );
          }
        else
          {
          currentArg += a;
          arguments.push_back( currentArg );
          currentArg.clear();
          isArgOpen = false;
          }
        }
      else
        {
        currentArg += a;
        }
      }
    else
      {
      std::size_t leftDelimiterPosition = a.find( this->m_LeftDelimiter );
      std::size_t rightDelimiterPosition = a.find( this->m_RightDelimiter );

      if( leftDelimiterPosition == std::string::npos )
        {
        if( rightDelimiterPosition == std::string::npos )
          {
          currentArg += a;
          arguments.push_back( currentArg );
          currentArg.clear();
          }
        else
          {
          itkExceptionMacro( "Incorrect command line specification." );
          }
        }
      else if( leftDelimiterPosition != std::string::npos &&
               rightDelimiterPosition != std::string::npos &&
               leftDelimiterPosition < rightDelimiterPosition )
        {
        if( rightDelimiterPosition < a.length() - 1 )
          {
          itkExceptionMacro( "Incorrect command line specification." );
          }
        currentArg += a;
        arguments.push_back( currentArg );
        currentArg.clear();
        isArgOpen = false;
        }
      else if( rightDelimiterPosition == std::string::npos &&
               leftDelimiterPosition != std::string::npos )
        {
        currentArg += a;
        isArgOpen = true;
        }
      }
    }

  return arguments;
}

CommandLineParser::OptionType::Pointer
CommandLineParser
::GetOption( std::string name )
{
  if( name.length() == 1 )
    {
    return this->GetOption( name.at( 0 ) );
    }

  OptionListType::iterator it;
  for( it = this->m_Options.begin(); it != this->m_Options.end(); it++ )
    {
    if( name.compare( (*it)->GetLongName() ) == 0 )
      {
      return *it;
      }
    }
  return NULL;
}

CommandLineParser::OptionType::Pointer
CommandLineParser
::GetOption( char name )
{
  OptionListType::iterator it;

  for( it = this->m_Options.begin(); it != this->m_Options.end(); it++ )
    {
    if( name == (*it)->GetShortName() )
      {
      return *it;
      }
    }
  return NULL;
}

void
CommandLineParser
::PrintMenu( std::ostream& os, Indent indent, bool printShortVersion ) const
{
  os << std::endl;
  os << "COMMAND: " << std::endl;
  os << indent << this->m_Command << std::endl;
  if( !this->m_CommandDescription.empty() && !printShortVersion )
    {
    std::stringstream ss1;
    ss1 << indent << indent;

    std::stringstream ss2;
    ss2 << this->m_CommandDescription;

    std::string description = this->BreakUpStringIntoNewLines(
        ss2.str(), ss1.str(), 80 );

    os << indent << indent << description << std::endl;
    }
  os << std::endl;
  os << "OPTIONS: " << std::endl;

  OptionListType::const_iterator it;
  for( it = this->m_Options.begin(); it != this->m_Options.end(); it++ )
    {
    os << indent;
    std::stringstream ss;
    ss << indent;

    if( (*it)->GetShortName() != '\0' )
      {
      os << "-" << (*it)->GetShortName();
      ss << Indent( 2 );
      if( !( (*it)->GetLongName() ).empty() )
        {
        os << ", " << "--" << (*it)->GetLongName() << " " << std::flush;
        ss << Indent( 5 + ( (*it)->GetLongName() ).length() );
        }
      else
        {
        os << " " << std::flush;
        ss << Indent( 1 );
        }
      }
    else
      {
      os << "--" << (*it)->GetLongName() << " " << std::flush;
      ss << Indent( 3 + ( (*it)->GetLongName() ).length() );
      }
    if( (*it)->GetNumberOfUsageOptions() > 0 )
      {
      os << (*it)->GetUsageOption( 0 ) << std::endl;
      for( unsigned int i = 1; i < (*it)->GetNumberOfUsageOptions(); i++ )
        {
        os << ss.str() << (*it)->GetUsageOption( i ) << std::endl;
        }
      }
    else
      {
      os << std::endl;
      }

    if( !( (*it)->GetDescription().empty() ) && !printShortVersion )
      {
      std::stringstream ss1;
      ss1 << indent << indent;

      std::stringstream ss2;
      ss2 << (*it)->GetDescription();

      std::string description = this->BreakUpStringIntoNewLines(
          ss2.str(), ss1.str(), 80 );

      os << indent << indent << description << std::endl;
      }
    if( !printShortVersion )
      {
      if( (*it)->GetValues().size() == 1 )
        {
        os << indent << indent << "<VALUES>: " << (*it)->GetValue( 0 );
        if( (*it)->GetParameters( 0 ).size() > 0 )
          {
          os << "[";
          if( (*it)->GetParameters( 0 ).size() == 1 )
            {
            os << (*it)->GetParameter( 0, 0 );
            }
          else
            {
            for( unsigned int i = 0;
                 i < (*it)->GetParameters( 0 ).size() - 1; i++ )
              {
              os << (*it)->GetParameter( 0, i ) << ",";
              }
            os << (*it)->GetParameter( 0, (*it)->GetParameters( 0 ).size() - 1 );
            }
          os << "]";
          }
        os << std::endl;
        }
      else if( (*it)->GetValues().size() > 1 )
        {
        os << indent << indent << "<VALUES>: ";
        for( unsigned int n = 0; n < (*it)->GetValues().size() - 1; n++ )
          {
          os << (*it)->GetValue( n );
          if( (*it)->GetParameters( n ).size() > 0 )
            {
            os << "[";
            if( (*it)->GetParameters( n ).size() == 1 )
              {
              os << (*it)->GetParameter( n, 0 ) << "], ";
              }
            else
              {
              for( unsigned int i = 0;
                   i < (*it)->GetParameters( n ).size() - 1; i++ )
                {
                os << (*it)->GetParameter( n, i ) << ",";
                }
              os << (*it)->GetParameter( n,
                                         (*it)->GetParameters( n ).size() - 1 ) << "], ";
              }
            }
          else
            {
            os << ", ";
            }
          }

        unsigned int nn = (*it)->GetValues().size() - 1;

        os << (*it)->GetValue( nn );
        if( (*it)->GetParameters( nn ).size() > 0 )
          {
          os << "[";
          if( (*it)->GetParameters( nn ).size() == 1 )
            {
            os << (*it)->GetParameter( nn, 0 ) << "]";
            }
          else
            {
            for( unsigned int i = 0;
                 i < (*it)->GetParameters( nn ).size() - 1; i++ )
              {
              os << (*it)->GetParameter( nn, i ) << ",";
              }
            os << (*it)->GetParameter( nn,
                                       (*it)->GetParameters( nn ).size() - 1 ) << "]";
            }
          }
        }
      os << std::endl;
      }
    }
}

std::string
CommandLineParser
::BreakUpStringIntoNewLines( std::string longString,
                             std::string indentString, unsigned int numberOfCharactersPerLine ) const
{
  std::vector<std::string> tokens;

  this->TokenizeString( longString, tokens, " " );

  std::string  newString( "" );
  unsigned int currentTokenId = 0;
  unsigned int currentLineLength = 0;
  while( currentTokenId < tokens.size() )
    {
    if( tokens[currentTokenId].length() >= numberOfCharactersPerLine )
      {
      newString += ( std::string( "\n" ) + tokens[currentTokenId]
                     + std::string( "\n" ) );
      currentTokenId++;
      currentLineLength = 0;
      }
    else if( currentTokenId < tokens.size() && currentLineLength
             + tokens[currentTokenId].length() > numberOfCharactersPerLine )
      {
      newString += ( std::string( "\n" ) + indentString );
      currentLineLength = 0;
      }
    else
      {
      newString += ( tokens[currentTokenId] + std::string( " " ) );
      currentLineLength += ( tokens[currentTokenId].length() + 1 );
      currentTokenId++;
      }
    }

  return newString;
}

void
CommandLineParser
::TokenizeString( std::string str, std::vector<std::string> & tokens,
                  std::string delimiters ) const
{
  // Skip delimiters at beginning.
  std::string::size_type lastPos = str.find_first_not_of( delimiters, 0 );
  // Find first "non-delimiter".
  std::string::size_type pos = str.find_first_of( delimiters, lastPos );

  while( std::string::npos != pos || std::string::npos != lastPos )
    {
    // Found a token, add it to the vector.
    tokens.push_back( str.substr( lastPos, pos - lastPos ) );
    // Skip delimiters.  Note the "not_of"
    lastPos = str.find_first_not_of( delimiters, pos );
    // Find next "non-delimiter"
    pos = str.find_first_of( delimiters, lastPos );
    }
}

/**
 * Standard "PrintSelf" method
 */
void
CommandLineParser
::PrintSelf( std::ostream& os, Indent indent) const
{
  Superclass::PrintSelf( os, indent );

  os << indent << "Command: " << this->m_Command << std::endl;
  os << indent << "Options: " << std::endl;

  OptionListType::const_iterator it;
  for( it = this->m_Options.begin(); it != this->m_Options.end(); it++ )
    {
    (*it)->Print( os, indent );
    }

  if( this->m_UnknownOptions.size() )
    {
    os << indent << "Unknown Options: " << std::endl;
    OptionListType::const_iterator its;
    for( its = this->m_UnknownOptions.begin();
         its != this->m_UnknownOptions.end(); its++ )
      {
      (*its)->Print( os, indent );
      }
    }
}
} // end namespace ants
} // end namespace itk
<commit_msg>BUG:  Negative volues weren't being processed on the command line correctly.<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    $RCSfile: antsCommandLineParser.cxx,v $
  Language:  C++
  Date:      $Date: 2009/01/22 22:43:11 $
  Version:   $Revision: 1.1 $

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "antsCommandLineParser.h"

#include <algorithm>

namespace itk
{
namespace ants
{
CommandLineParser
::CommandLineParser()
{
  this->m_Options.clear();
  this->m_Command.clear();
  this->m_CommandDescription.clear();
  this->m_UnknownOptions.clear();

  this->m_LeftDelimiter = '[';
  this->m_RightDelimiter = ']';
}

void
CommandLineParser
::AddOption( OptionType::Pointer option )
{
  if( ( option->GetShortName() != '\0' ||
        !this->GetOption( option->GetShortName() ) )
      || ( !option->GetLongName().empty() ||
           !this->GetOption( option->GetLongName() ) ) )
    {
    this->m_Options.push_back( option );
    }
  else
    {
    if( option->GetShortName() != '\0' &&
        this->GetOption( option->GetShortName() ) )
      {
      itkWarningMacro( "Duplicate short option '-"
                       << option->GetShortName() << "'" );
      }
    if( !( option->GetLongName().empty() ) &&
        this->GetOption( option->GetLongName() ) )
      {
      itkWarningMacro( "Duplicate long option '--"
                       << option->GetLongName() << "'" );
      }
    }
}

void
CommandLineParser
::Parse( unsigned int argc, char * *argv )
{
  std::vector<std::string> arguments =
    this->RegroupCommandLineArguments( argc, argv );

  unsigned int n = 0;

  this->m_Command = arguments[n++];

  while( n < arguments.size() )
    {
    std::string argument = arguments[n++];
    std::string name;

    name.clear();
    if( argument.find( "--" ) == 0 )
      {
      name = argument.substr( 2, argument.length() - 1 );
      }
    else if( argument.find( "-" ) == 0 && argument.find( "--" ) > 0 )
      {
      name = argument.substr( 1, 2 );
      }

    if( !( name.empty() ) && !atof( name.c_str() ) )
      {
      OptionType::Pointer option = this->GetOption( name );
      if( !option )
        {
        OptionType::Pointer unknownOption = OptionType::New();
        if( name.length() > 1 )
          {
          unknownOption->SetLongName( name );
          }
        else
          {
          unknownOption->SetShortName( name.at( 0 ) );
          }
        if( n == arguments.size() )
          {
          unknownOption->AddValue( "1",
                                   this->m_LeftDelimiter, this->m_RightDelimiter );
          }
        else
          {
          for( unsigned int m = n; m < arguments.size(); m++ )
            {
            std::string value = arguments[m];
            if( value.find( "-" ) != 0 )
              {
              unknownOption->AddValue( value,
                                       this->m_LeftDelimiter, this->m_RightDelimiter );
              }
            else
              {
              if( m == n )
                {
                unknownOption->AddValue( "1",
                                         this->m_LeftDelimiter, this->m_RightDelimiter );
                }
              n = m;
              break;
              }
            }
          }
        this->m_UnknownOptions.push_back( unknownOption );
        }
      else  // the option exists
        {
        if( n == arguments.size() )
          {
          option->AddValue( "1",
                            this->m_LeftDelimiter, this->m_RightDelimiter );
          }
        else
          {
          for( unsigned int m = n; m < arguments.size(); m++ )
            {
            std::string value = arguments[m];
            if( value.find( "-" ) != 0 || atof( value.c_str() ) )
              {
              option->AddValue( value,
                                this->m_LeftDelimiter, this->m_RightDelimiter );
              }
            else
              {
              if( m == n )
                {
                option->AddValue( "1",
                                  this->m_LeftDelimiter, this->m_RightDelimiter );
                }
              n = m;
              break;
              }
            }
          }
        }
      }
    }
}

std::vector<std::string>
CommandLineParser
::RegroupCommandLineArguments( unsigned int argc, char * *argv )
{
  /**
   * Inclusion of this function allows the user to use spaces inside
   * the left and right delimiters.  Also replace other left and right
   * delimiters.
   */
  std::vector<std::string> arguments;

  std::string currentArg( "" );
  bool        isArgOpen = false;

  for( unsigned int n = 0; n < argc; n++ )
    {
    std::string a( argv[n] );

    // replace left delimiters
    std::replace( a.begin(), a.end(), '{', '[' );
    std::replace( a.begin(), a.end(), '(', '[' );
    std::replace( a.begin(), a.end(), '<', '[' );

    // replace right delimiters
    std::replace( a.begin(), a.end(), '}', ']' );
    std::replace( a.begin(), a.end(), ')', ']' );
    std::replace( a.begin(), a.end(), '>', ']' );

    if( isArgOpen )
      {
      std::size_t leftDelimiterPosition = a.find( this->m_LeftDelimiter );
      if( leftDelimiterPosition != std::string::npos )
        {
        itkExceptionMacro( "Incorrect command line specification." );
        }

      std::size_t rightDelimiterPosition = a.find( this->m_RightDelimiter );
      if( rightDelimiterPosition != std::string::npos )
        {
        if( rightDelimiterPosition < a.length() - 1 )
          {
          itkExceptionMacro( "Incorrect command line specification." );
          }
        else
          {
          currentArg += a;
          arguments.push_back( currentArg );
          currentArg.clear();
          isArgOpen = false;
          }
        }
      else
        {
        currentArg += a;
        }
      }
    else
      {
      std::size_t leftDelimiterPosition = a.find( this->m_LeftDelimiter );
      std::size_t rightDelimiterPosition = a.find( this->m_RightDelimiter );

      if( leftDelimiterPosition == std::string::npos )
        {
        if( rightDelimiterPosition == std::string::npos )
          {
          currentArg += a;
          arguments.push_back( currentArg );
          currentArg.clear();
          }
        else
          {
          itkExceptionMacro( "Incorrect command line specification." );
          }
        }
      else if( leftDelimiterPosition != std::string::npos &&
               rightDelimiterPosition != std::string::npos &&
               leftDelimiterPosition < rightDelimiterPosition )
        {
        if( rightDelimiterPosition < a.length() - 1 )
          {
          itkExceptionMacro( "Incorrect command line specification." );
          }
        currentArg += a;
        arguments.push_back( currentArg );
        currentArg.clear();
        isArgOpen = false;
        }
      else if( rightDelimiterPosition == std::string::npos &&
               leftDelimiterPosition != std::string::npos )
        {
        currentArg += a;
        isArgOpen = true;
        }
      }
    }

  return arguments;
}

CommandLineParser::OptionType::Pointer
CommandLineParser
::GetOption( std::string name )
{
  if( name.length() == 1 )
    {
    return this->GetOption( name.at( 0 ) );
    }

  OptionListType::iterator it;
  for( it = this->m_Options.begin(); it != this->m_Options.end(); it++ )
    {
    if( name.compare( (*it)->GetLongName() ) == 0 )
      {
      return *it;
      }
    }
  return NULL;
}

CommandLineParser::OptionType::Pointer
CommandLineParser
::GetOption( char name )
{
  OptionListType::iterator it;

  for( it = this->m_Options.begin(); it != this->m_Options.end(); it++ )
    {
    if( name == (*it)->GetShortName() )
      {
      return *it;
      }
    }
  return NULL;
}

void
CommandLineParser
::PrintMenu( std::ostream& os, Indent indent, bool printShortVersion ) const
{
  os << std::endl;
  os << "COMMAND: " << std::endl;
  os << indent << this->m_Command << std::endl;
  if( !this->m_CommandDescription.empty() && !printShortVersion )
    {
    std::stringstream ss1;
    ss1 << indent << indent;

    std::stringstream ss2;
    ss2 << this->m_CommandDescription;

    std::string description = this->BreakUpStringIntoNewLines(
        ss2.str(), ss1.str(), 80 );

    os << indent << indent << description << std::endl;
    }
  os << std::endl;
  os << "OPTIONS: " << std::endl;

  OptionListType::const_iterator it;
  for( it = this->m_Options.begin(); it != this->m_Options.end(); it++ )
    {
    os << indent;
    std::stringstream ss;
    ss << indent;

    if( (*it)->GetShortName() != '\0' )
      {
      os << "-" << (*it)->GetShortName();
      ss << Indent( 2 );
      if( !( (*it)->GetLongName() ).empty() )
        {
        os << ", " << "--" << (*it)->GetLongName() << " " << std::flush;
        ss << Indent( 5 + ( (*it)->GetLongName() ).length() );
        }
      else
        {
        os << " " << std::flush;
        ss << Indent( 1 );
        }
      }
    else
      {
      os << "--" << (*it)->GetLongName() << " " << std::flush;
      ss << Indent( 3 + ( (*it)->GetLongName() ).length() );
      }
    if( (*it)->GetNumberOfUsageOptions() > 0 )
      {
      os << (*it)->GetUsageOption( 0 ) << std::endl;
      for( unsigned int i = 1; i < (*it)->GetNumberOfUsageOptions(); i++ )
        {
        os << ss.str() << (*it)->GetUsageOption( i ) << std::endl;
        }
      }
    else
      {
      os << std::endl;
      }

    if( !( (*it)->GetDescription().empty() ) && !printShortVersion )
      {
      std::stringstream ss1;
      ss1 << indent << indent;

      std::stringstream ss2;
      ss2 << (*it)->GetDescription();

      std::string description = this->BreakUpStringIntoNewLines(
          ss2.str(), ss1.str(), 80 );

      os << indent << indent << description << std::endl;
      }
    if( !printShortVersion )
      {
      if( (*it)->GetValues().size() == 1 )
        {
        os << indent << indent << "<VALUES>: " << (*it)->GetValue( 0 );
        if( (*it)->GetParameters( 0 ).size() > 0 )
          {
          os << "[";
          if( (*it)->GetParameters( 0 ).size() == 1 )
            {
            os << (*it)->GetParameter( 0, 0 );
            }
          else
            {
            for( unsigned int i = 0;
                 i < (*it)->GetParameters( 0 ).size() - 1; i++ )
              {
              os << (*it)->GetParameter( 0, i ) << ",";
              }
            os << (*it)->GetParameter( 0, (*it)->GetParameters( 0 ).size() - 1 );
            }
          os << "]";
          }
        os << std::endl;
        }
      else if( (*it)->GetValues().size() > 1 )
        {
        os << indent << indent << "<VALUES>: ";
        for( unsigned int n = 0; n < (*it)->GetValues().size() - 1; n++ )
          {
          os << (*it)->GetValue( n );
          if( (*it)->GetParameters( n ).size() > 0 )
            {
            os << "[";
            if( (*it)->GetParameters( n ).size() == 1 )
              {
              os << (*it)->GetParameter( n, 0 ) << "], ";
              }
            else
              {
              for( unsigned int i = 0;
                   i < (*it)->GetParameters( n ).size() - 1; i++ )
                {
                os << (*it)->GetParameter( n, i ) << ",";
                }
              os << (*it)->GetParameter( n,
                                         (*it)->GetParameters( n ).size() - 1 ) << "], ";
              }
            }
          else
            {
            os << ", ";
            }
          }

        unsigned int nn = (*it)->GetValues().size() - 1;

        os << (*it)->GetValue( nn );
        if( (*it)->GetParameters( nn ).size() > 0 )
          {
          os << "[";
          if( (*it)->GetParameters( nn ).size() == 1 )
            {
            os << (*it)->GetParameter( nn, 0 ) << "]";
            }
          else
            {
            for( unsigned int i = 0;
                 i < (*it)->GetParameters( nn ).size() - 1; i++ )
              {
              os << (*it)->GetParameter( nn, i ) << ",";
              }
            os << (*it)->GetParameter( nn,
                                       (*it)->GetParameters( nn ).size() - 1 ) << "]";
            }
          }
        }
      os << std::endl;
      }
    }
}

std::string
CommandLineParser
::BreakUpStringIntoNewLines( std::string longString,
                             std::string indentString, unsigned int numberOfCharactersPerLine ) const
{
  std::vector<std::string> tokens;

  this->TokenizeString( longString, tokens, " " );

  std::string  newString( "" );
  unsigned int currentTokenId = 0;
  unsigned int currentLineLength = 0;
  while( currentTokenId < tokens.size() )
    {
    if( tokens[currentTokenId].length() >= numberOfCharactersPerLine )
      {
      newString += ( std::string( "\n" ) + tokens[currentTokenId]
                     + std::string( "\n" ) );
      currentTokenId++;
      currentLineLength = 0;
      }
    else if( currentTokenId < tokens.size() && currentLineLength
             + tokens[currentTokenId].length() > numberOfCharactersPerLine )
      {
      newString += ( std::string( "\n" ) + indentString );
      currentLineLength = 0;
      }
    else
      {
      newString += ( tokens[currentTokenId] + std::string( " " ) );
      currentLineLength += ( tokens[currentTokenId].length() + 1 );
      currentTokenId++;
      }
    }

  return newString;
}

void
CommandLineParser
::TokenizeString( std::string str, std::vector<std::string> & tokens,
                  std::string delimiters ) const
{
  // Skip delimiters at beginning.
  std::string::size_type lastPos = str.find_first_not_of( delimiters, 0 );
  // Find first "non-delimiter".
  std::string::size_type pos = str.find_first_of( delimiters, lastPos );

  while( std::string::npos != pos || std::string::npos != lastPos )
    {
    // Found a token, add it to the vector.
    tokens.push_back( str.substr( lastPos, pos - lastPos ) );
    // Skip delimiters.  Note the "not_of"
    lastPos = str.find_first_not_of( delimiters, pos );
    // Find next "non-delimiter"
    pos = str.find_first_of( delimiters, lastPos );
    }
}

/**
 * Standard "PrintSelf" method
 */
void
CommandLineParser
::PrintSelf( std::ostream& os, Indent indent) const
{
  Superclass::PrintSelf( os, indent );

  os << indent << "Command: " << this->m_Command << std::endl;
  os << indent << "Options: " << std::endl;

  OptionListType::const_iterator it;
  for( it = this->m_Options.begin(); it != this->m_Options.end(); it++ )
    {
    (*it)->Print( os, indent );
    }

  if( this->m_UnknownOptions.size() )
    {
    os << indent << "Unknown Options: " << std::endl;
    OptionListType::const_iterator its;
    for( its = this->m_UnknownOptions.begin();
         its != this->m_UnknownOptions.end(); its++ )
      {
      (*its)->Print( os, indent );
      }
    }
}
} // end namespace ants
} // end namespace itk
<|endoftext|>


<commit_before>/*
 * ElevationChangeDetection.cpp
 *
 *  Created on: Mar 26, 2015
 *      Author: Martin Wermelinger
 *   Institute: ETH Zurich, Autonomous Systems Lab
 */

#include "elevation_change_detection/ElevationChangeDetection.hpp"

#include <grid_map_msgs/GetGridMap.h>

// Eigenvalues
#include <Eigen/Dense>

using namespace Eigen;
using namespace grid_map;

namespace elevation_change_detection {

ElevationChangeDetection::ElevationChangeDetection(ros::NodeHandle& nodeHandle)
    : nodeHandle_(nodeHandle),
      type_("elevation")
{
  ROS_INFO("Elevation change detection node started.");

  readParameters();

  submapClient_ = nodeHandle_.serviceClient<grid_map_msgs::GetGridMap>(submapServiceName_);
  elevationChangePublisher_ = nodeHandle_.advertise<grid_map_msgs::GridMap>("elevation_change_map", 1, true);
  groundTruthPublisher_ = nodeHandle_.advertise<grid_map_msgs::GridMap>("ground_truth_map", 1, true);

  updateTimer_ = nodeHandle_.createTimer(updateDuration_,
                                         &ElevationChangeDetection::updateTimerCallback, this);

  requestedMapTypes_.push_back(type_);
}

ElevationChangeDetection::~ElevationChangeDetection()
{
  updateTimer_.stop();
  nodeHandle_.shutdown();
}

bool ElevationChangeDetection::readParameters()
{
  nodeHandle_.param("submap_service", submapServiceName_, std::string("/get_grid_map"));

  double updateRate;
  nodeHandle_.param("update_rate", updateRate, 1.0);
  updateDuration_.fromSec(1.0 / updateRate);

  nodeHandle_.param("map_frame_id", mapFrameId_, std::string("map"));
  std::string robotFrameId;
  nodeHandle_.param("robot_frame_id", robotFrameId, std::string("base"));
  double mapCenterX, mapCenterY;
  nodeHandle_.param("map_center_x", mapCenterX, 0.0);
  nodeHandle_.param("map_center_y", mapCenterY, 0.0);
  submapPoint_.header.frame_id = robotFrameId;
  submapPoint_.point.x = mapCenterX;
  submapPoint_.point.y = mapCenterY;
  submapPoint_.point.z = 0.0;

  nodeHandle_.param("map_length_x", mapLength_.x(), 5.0);
  nodeHandle_.param("map_length_y", mapLength_.y(), 5.0);

  nodeHandle_.param("threshold", threshold_, 0.0);

  return true;
}

bool ElevationChangeDetection::loadElevationMap(const std::string& pathToBag, const std::string& topicName)
{
  return grid_map::GridMapRosConverter::loadFromBag(pathToBag, topicName, groundTruthMap_);
}

void ElevationChangeDetection::updateTimerCallback(const ros::TimerEvent& timerEvent)
{
  grid_map_msgs::GridMap mapMessage;
  ROS_DEBUG("Sending request to %s.", submapServiceName_.c_str());
  submapClient_.waitForExistence();
  ROS_DEBUG("Sending request to %s.", submapServiceName_.c_str());
  if (getGridMap(mapMessage)) {
    grid_map::GridMap elevationMap;
    grid_map::GridMapRosConverter::fromMessage(mapMessage, elevationMap);
    computeElevationChange(elevationMap);

    // Publish elevation change map.
    if (!publishElevationChangeMap(elevationMap)) ROS_DEBUG("Elevation change map has not been broadcasted.");
    if (!publishGroundTruthMap(groundTruthMap_)) ROS_DEBUG("Ground truth map has not been broadcasted.");
  } else {
    ROS_WARN("Failed to retrieve elevation grid map.");
  }
}

bool ElevationChangeDetection::getGridMap(grid_map_msgs::GridMap& map)
{
  submapPoint_.header.stamp = ros::Time(0);
  geometry_msgs::PointStamped submapPointTransformed;

  try {
    transformListener_.transformPoint(mapFrameId_, submapPoint_, submapPointTransformed);
  } catch (tf::TransformException &ex) {
    ROS_ERROR("%s", ex.what());
  }

  grid_map_msgs::GetGridMap submapService;
  submapService.request.position_x = submapPointTransformed.point.x;
  submapService.request.position_y = submapPointTransformed.point.y;
  submapService.request.length_x = mapLength_.x();
  submapService.request.length_y = mapLength_.y();
  submapService.request.layers.resize(requestedMapTypes_.size());

  for (unsigned int i = 0; i < requestedMapTypes_.size(); ++i) {
    submapService.request.layers[i] = requestedMapTypes_[i];
  }

  if (!submapClient_.call(submapService)) return false;
  map = submapService.response.map;
  return true;
}

void ElevationChangeDetection::computeElevationChange(grid_map::GridMap& elevationMap)
{
  elevationMap.add("elevation_change", elevationMap.get(type_));
  std::vector<std::string> validTypes;
  std::vector<std::string> basicLayers;
  validTypes.push_back(type_);
  basicLayers.push_back("elevation_change");
  elevationMap.setBasicLayers(basicLayers);
  elevationMap.clear();

  for (GridMapIterator iterator(elevationMap);
      !iterator.isPassedEnd(); ++iterator) {
    // Check if elevation map has valid value
    if (!elevationMap.isValid(*iterator, validTypes)) continue;
    double height = elevationMap.at(type_, *iterator);

    // Get the ground truth height
    Vector2d position, groundTruthPosition;
    Array2i groundTruthIndex;
    elevationMap.getPosition(*iterator, position);
    groundTruthMap_.getIndex(position, groundTruthIndex);
    if (!groundTruthMap_.isValid(groundTruthIndex, validTypes)) continue;
    double groundTruthHeight = groundTruthMap_.at(type_, groundTruthIndex);

    // Add to elevation change map
    double diffElevation = std::abs(height - groundTruthHeight);
    if (diffElevation <= threshold_) continue;
    elevationMap.at("elevation_change", *iterator) = diffElevation;
  }
}

bool ElevationChangeDetection::publishElevationChangeMap(const grid_map::GridMap& map)
{
  if (elevationChangePublisher_.getNumSubscribers() < 1) return false;
  grid_map_msgs::GridMap message;
  GridMapRosConverter::toMessage(map, message);
  elevationChangePublisher_.publish(message);
  ROS_DEBUG("Elevation map raw has been published.");
  return true;
}

bool ElevationChangeDetection::publishGroundTruthMap(const grid_map::GridMap& map)
{
  if (groundTruthPublisher_.getNumSubscribers() < 1) return false;
  grid_map_msgs::GridMap message;
  GridMapRosConverter::toMessage(map, message);
  groundTruthPublisher_.publish(message);
  ROS_DEBUG("Ground truth map raw has been published.");
  return true;
}

} /* namespace elevation_change_detection */
<commit_msg>Added loading from rosbag.<commit_after>/*
 * ElevationChangeDetection.cpp
 *
 *  Created on: Mar 26, 2015
 *      Author: Martin Wermelinger
 *   Institute: ETH Zurich, Autonomous Systems Lab
 */

#include "elevation_change_detection/ElevationChangeDetection.hpp"

#include <grid_map_msgs/GetGridMap.h>

// Eigenvalues
#include <Eigen/Dense>

using namespace Eigen;
using namespace grid_map;

namespace elevation_change_detection {

ElevationChangeDetection::ElevationChangeDetection(ros::NodeHandle& nodeHandle)
    : nodeHandle_(nodeHandle),
      type_("elevation")
{
  ROS_INFO("Elevation change detection node started.");

  readParameters();

  submapClient_ = nodeHandle_.serviceClient<grid_map_msgs::GetGridMap>(submapServiceName_);
  elevationChangePublisher_ = nodeHandle_.advertise<grid_map_msgs::GridMap>("elevation_change_map", 1, true);
  groundTruthPublisher_ = nodeHandle_.advertise<grid_map_msgs::GridMap>("ground_truth_map", 1, true);

  updateTimer_ = nodeHandle_.createTimer(updateDuration_,
                                         &ElevationChangeDetection::updateTimerCallback, this);

  requestedMapTypes_.push_back(type_);
}

ElevationChangeDetection::~ElevationChangeDetection()
{
  updateTimer_.stop();
  nodeHandle_.shutdown();
}

bool ElevationChangeDetection::readParameters()
{
  nodeHandle_.param("submap_service", submapServiceName_, std::string("/get_grid_map"));

  double updateRate;
  nodeHandle_.param("update_rate", updateRate, 1.0);
  updateDuration_.fromSec(1.0 / updateRate);

  nodeHandle_.param("map_frame_id", mapFrameId_, std::string("map"));
  std::string robotFrameId;
  nodeHandle_.param("robot_frame_id", robotFrameId, std::string("base"));
  double mapCenterX, mapCenterY;
  nodeHandle_.param("map_center_x", mapCenterX, 0.0);
  nodeHandle_.param("map_center_y", mapCenterY, 0.0);
  submapPoint_.header.frame_id = robotFrameId;
  submapPoint_.point.x = mapCenterX;
  submapPoint_.point.y = mapCenterY;
  submapPoint_.point.z = 0.0;

  nodeHandle_.param("map_length_x", mapLength_.x(), 5.0);
  nodeHandle_.param("map_length_y", mapLength_.y(), 5.0);

  nodeHandle_.param("threshold", threshold_, 0.0);

  std::string bagTopicName_, pathToBag_;
  nodeHandle_.param("bag_topic_name", bagTopicName_, std::string("grid_map"));
  nodeHandle_.param("path_to_bag", pathToBag_, std::string("lee_ground_truth.bag"));
  loadElevationMap(pathToBag_, bagTopicName_);
  if (!groundTruthMap_.exists(type_)) ROS_ERROR("Can't find bag or topic of the ground truth map!");

  return true;
}

bool ElevationChangeDetection::loadElevationMap(const std::string& pathToBag, const std::string& topicName)
{
  return grid_map::GridMapRosConverter::loadFromBag(pathToBag, topicName, groundTruthMap_);
}

void ElevationChangeDetection::updateTimerCallback(const ros::TimerEvent& timerEvent)
{
  grid_map_msgs::GridMap mapMessage;
  ROS_DEBUG("Sending request to %s.", submapServiceName_.c_str());
  submapClient_.waitForExistence();
  ROS_DEBUG("Sending request to %s.", submapServiceName_.c_str());
  if (getGridMap(mapMessage)) {
    grid_map::GridMap elevationMap;
    grid_map::GridMapRosConverter::fromMessage(mapMessage, elevationMap);
    computeElevationChange(elevationMap);

    // Publish elevation change map.
    if (!publishElevationChangeMap(elevationMap)) ROS_DEBUG("Elevation change map has not been broadcasted.");
    if (!publishGroundTruthMap(groundTruthMap_)) ROS_DEBUG("Ground truth map has not been broadcasted.");
  } else {
    ROS_WARN("Failed to retrieve elevation grid map.");
  }
}

bool ElevationChangeDetection::getGridMap(grid_map_msgs::GridMap& map)
{
  submapPoint_.header.stamp = ros::Time(0);
  geometry_msgs::PointStamped submapPointTransformed;

  try {
    transformListener_.transformPoint(mapFrameId_, submapPoint_, submapPointTransformed);
  } catch (tf::TransformException &ex) {
    ROS_ERROR("%s", ex.what());
  }

  grid_map_msgs::GetGridMap submapService;
  submapService.request.position_x = submapPointTransformed.point.x;
  submapService.request.position_y = submapPointTransformed.point.y;
  submapService.request.length_x = mapLength_.x();
  submapService.request.length_y = mapLength_.y();
  submapService.request.layers.resize(requestedMapTypes_.size());

  for (unsigned int i = 0; i < requestedMapTypes_.size(); ++i) {
    submapService.request.layers[i] = requestedMapTypes_[i];
  }

  if (!submapClient_.call(submapService)) return false;
  map = submapService.response.map;
  return true;
}

void ElevationChangeDetection::computeElevationChange(grid_map::GridMap& elevationMap)
{
  elevationMap.add("elevation_change", elevationMap.get(type_));
  std::vector<std::string> validTypes;
  std::vector<std::string> basicLayers;
  validTypes.push_back(type_);
  basicLayers.push_back("elevation_change");
  elevationMap.setBasicLayers(basicLayers);
  elevationMap.clear();

  for (GridMapIterator iterator(elevationMap);
      !iterator.isPassedEnd(); ++iterator) {
    // Check if elevation map has valid value
    if (!elevationMap.isValid(*iterator, validTypes)) continue;
    double height = elevationMap.at(type_, *iterator);

    // Get the ground truth height
    Vector2d position, groundTruthPosition;
    Array2i groundTruthIndex;
    elevationMap.getPosition(*iterator, position);
    groundTruthMap_.getIndex(position, groundTruthIndex);
    if (!groundTruthMap_.isValid(groundTruthIndex, validTypes)) continue;
    double groundTruthHeight = groundTruthMap_.at(type_, groundTruthIndex);

    // Add to elevation change map
    double diffElevation = std::abs(height - groundTruthHeight);
    if (diffElevation <= threshold_) continue;
    elevationMap.at("elevation_change", *iterator) = diffElevation;
  }
}

bool ElevationChangeDetection::publishElevationChangeMap(const grid_map::GridMap& map)
{
  if (elevationChangePublisher_.getNumSubscribers() < 1) return false;
  grid_map_msgs::GridMap message;
  GridMapRosConverter::toMessage(map, message);
  elevationChangePublisher_.publish(message);
  ROS_DEBUG("Elevation map raw has been published.");
  return true;
}

bool ElevationChangeDetection::publishGroundTruthMap(const grid_map::GridMap& map)
{
  if (groundTruthPublisher_.getNumSubscribers() < 1) return false;
  grid_map_msgs::GridMap message;
  GridMapRosConverter::toMessage(map, message);
  groundTruthPublisher_.publish(message);
  ROS_DEBUG("Ground truth map raw has been published.");
  return true;
}

} /* namespace elevation_change_detection */
<|endoftext|>