mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-16 10:22:15 -05:00
Initial commit of ResInsight version 0.4.8
This commit is contained in:
1 parent
a680bf941e
commit
dfe97efb1b
657 files changed
+176690
No files matched your search
@@ -0,0 +1,78 @@
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
project(LibCore)
|
||||
|
||||
|
||||
# Use our strict compile flags
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CEE_STRICT_CXX_FLAGS}")
|
||||
|
||||
|
||||
set(CEE_HEADER_FILES
|
||||
cvfArray.h
|
||||
cvfArray.inl
|
||||
cvfAssert.h
|
||||
cvfBase.h
|
||||
cvfBase64.h
|
||||
cvfCharArray.h
|
||||
cvfCollection.h
|
||||
cvfCollection.inl
|
||||
cvfColor3.h
|
||||
cvfColor4.h
|
||||
cvfConfigCore.h
|
||||
cvfDebugTimer.h
|
||||
cvfFlags.h
|
||||
cvfFlags.inl
|
||||
cvfFunctorRange.h
|
||||
cvfLibCore.h
|
||||
cvfLogger.h
|
||||
cvfMath.h
|
||||
cvfMath.inl
|
||||
cvfMatrix3.h
|
||||
cvfMatrix3.inl
|
||||
cvfMatrix4.h
|
||||
cvfMatrix4.inl
|
||||
cvfObject.h
|
||||
cvfObject.inl
|
||||
cvfPlane.h
|
||||
cvfQuat.h
|
||||
cvfQuat.inl
|
||||
cvfRect.h
|
||||
cvfRect.inl
|
||||
cvfString.h
|
||||
cvfSystem.h
|
||||
cvfTBBControl.h
|
||||
cvfTimer.h
|
||||
cvfTrace.h
|
||||
cvfValueArray.h
|
||||
cvfVector2.h
|
||||
cvfVector2.inl
|
||||
cvfVector3.h
|
||||
cvfVector3.inl
|
||||
cvfVector4.h
|
||||
cvfVector4.inl
|
||||
cvfVersion.h
|
||||
)
|
||||
|
||||
set(CEE_SOURCE_FILES
|
||||
cvfAssert.cpp
|
||||
cvfBase64.cpp
|
||||
cvfCharArray.cpp
|
||||
cvfColor3.cpp
|
||||
cvfColor4.cpp
|
||||
cvfDebugTimer.cpp
|
||||
cvfLogger.cpp
|
||||
cvfMath.cpp
|
||||
cvfObject.cpp
|
||||
cvfPlane.cpp
|
||||
cvfString.cpp
|
||||
cvfSystem.cpp
|
||||
cvfTimer.cpp
|
||||
cvfTBBControl.cpp
|
||||
cvfTrace.cpp
|
||||
cvfVector2.cpp
|
||||
cvfVector3.cpp
|
||||
cvfVector4.cpp
|
||||
)
|
||||
|
||||
add_library(${PROJECT_NAME} ${CEE_HEADER_FILES} ${CEE_SOURCE_FILES})
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfObject.h"
|
||||
#include "cvfValueArray.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Templated array designed for high performance and no overhead over C arrays.
|
||||
//
|
||||
//==================================================================================================
|
||||
template <typename T>
|
||||
class Array : public Object, public ValueArray<T>
|
||||
{
|
||||
public:
|
||||
Array();
|
||||
Array(const Array& other);
|
||||
Array(const T* data, size_t size);
|
||||
explicit Array(size_t size);
|
||||
explicit Array(const ValueArray<T>& other);
|
||||
explicit Array(const std::vector<T>& other);
|
||||
~Array();
|
||||
|
||||
inline const T& operator[](size_t index) const;
|
||||
inline T& operator[](size_t index);
|
||||
Array& operator=(Array rhs);
|
||||
|
||||
void assign(const T* data, size_t size);
|
||||
void assign(const std::vector<T>& data);
|
||||
void resize(size_t size);
|
||||
void clear();
|
||||
inline virtual size_t size() const;
|
||||
|
||||
inline void set(size_t index, const T& val);
|
||||
inline void setAll(const T& val);
|
||||
inline void setConsecutive(const T& startVal);
|
||||
inline const T& get(size_t index) const;
|
||||
inline virtual T val(size_t index) const;
|
||||
|
||||
inline const T* ptr() const;
|
||||
inline T* ptr();
|
||||
inline const T* ptr(size_t index) const;
|
||||
inline T* ptr(size_t index);
|
||||
|
||||
void setSharedPtr(T* data, size_t size);
|
||||
void setPtr(T* data, size_t size);
|
||||
|
||||
void copyData(const T* source, size_t numElementsToCopy, size_t destIndex);
|
||||
void copyData(const Array<T>& source, size_t numElementsToCopy, size_t destIndex, size_t sourceIndex);
|
||||
|
||||
template<typename U>
|
||||
void copyConvertedData(const Array<U>& source, size_t numElementsToCopy, size_t destIndex, size_t sourceIndex);
|
||||
|
||||
template<typename U>
|
||||
ref<Array<T> > extractElements(const Array<U>& elementIndices) const;
|
||||
|
||||
void toStdVector(std::vector<T>* vec) const;
|
||||
|
||||
size_t capacity() const;
|
||||
void reserve(size_t capacity);
|
||||
void squeeze();
|
||||
void setSizeZero();
|
||||
inline void add(const T& val);
|
||||
|
||||
T min(size_t* index = 0) const;
|
||||
T max(size_t* index = 0) const;
|
||||
|
||||
void swap(Array& other);
|
||||
|
||||
// Basic iterator support to be able to utilize STL algorithms
|
||||
public:
|
||||
typedef T* iterator;
|
||||
typedef const T* const_iterator;
|
||||
|
||||
inline iterator begin() { return m_data; }
|
||||
inline iterator end() { return m_data + m_size; }
|
||||
inline const_iterator begin() const { return m_data; }
|
||||
inline const_iterator end() const { return m_data + m_size; }
|
||||
|
||||
private:
|
||||
void ground();
|
||||
|
||||
private:
|
||||
size_t m_size; ///< Number of elements/items in array
|
||||
size_t m_capacity; ///< Size of the allocated buffer
|
||||
T* m_data; ///< Array holding the actual data
|
||||
bool m_sharedData; ///< True if the data member is shared with another object and cannot be changed
|
||||
};
|
||||
|
||||
|
||||
// Only works for simple types that don't require copy operators.
|
||||
typedef Array<int> IntArray;
|
||||
typedef Array<uint> UIntArray;
|
||||
typedef Array<ushort> UShortArray;
|
||||
typedef Array<ubyte> UByteArray;
|
||||
typedef Array<float> FloatArray;
|
||||
typedef Array<double> DoubleArray;
|
||||
typedef Array<Vec2f> Vec2fArray;
|
||||
typedef Array<Vec2d> Vec2dArray;
|
||||
typedef Array<Vec3f> Vec3fArray;
|
||||
typedef Array<Vec3d> Vec3dArray;
|
||||
typedef Array<Vec4f> Vec4fArray;
|
||||
typedef Array<Vec4d> Vec4dArray;
|
||||
typedef Array<Color3ub> Color3ubArray;
|
||||
typedef Array<Color3f> Color3fArray;
|
||||
typedef Array<Color4ub> Color4ubArray;
|
||||
|
||||
}
|
||||
|
||||
#include "cvfArray.inl"
|
||||
@@ -0,0 +1,769 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::Array
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// Templated version of a simple array designed for high performance and no overhead over C arrays
|
||||
/// in release (non-check builds).
|
||||
///
|
||||
/// Will only work on simple types and classes that do not rely on a constructor or
|
||||
/// destructor (as they are not called).
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Create an empty array
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
Array<T>::Array()
|
||||
{
|
||||
ground();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Create an array with the given number of elements
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
Array<T>::Array(size_t size)
|
||||
{
|
||||
CVF_ASSERT(size > 0);
|
||||
ground();
|
||||
resize(size);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Create the array and assign (copy) the given data
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
Array<T>::Array(const T* data, size_t size)
|
||||
{
|
||||
CVF_ASSERT(data);
|
||||
CVF_ASSERT(size > 0);
|
||||
|
||||
ground();
|
||||
assign(data, size);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Create the array and assign (copy) the given data
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
Array<T>::Array(const Array& other)
|
||||
: Object(), ValueArray<T>()
|
||||
{
|
||||
ground();
|
||||
|
||||
if (other.size() > 0)
|
||||
{
|
||||
assign(other.m_data, other.size());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Explicit constructor to create the array and assign (copy) the passed value array
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
Array<T>::Array(const ValueArray<T>& other)
|
||||
{
|
||||
ground();
|
||||
|
||||
if (other.size() > 0)
|
||||
{
|
||||
resize(other.size());
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < other.size(); i++)
|
||||
{
|
||||
set(i, other.val(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Explicit constructor to create the array and assign (copy) the passed std::vector
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
Array<T>::Array(const std::vector<T>& other)
|
||||
{
|
||||
ground();
|
||||
|
||||
if (other.size() > 0)
|
||||
{
|
||||
assign(other);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Init all members
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void Array<T>::ground()
|
||||
{
|
||||
m_size = 0;
|
||||
m_data = NULL;
|
||||
m_capacity = 0;
|
||||
m_sharedData = false;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Destructor. Deletes the data.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
Array<T>::~Array()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns a const reference to the element at the given index.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
inline const T& Array<T>::operator[] (size_t index) const
|
||||
{
|
||||
CVF_TIGHT_ASSERT(this && m_data);
|
||||
CVF_TIGHT_ASSERT(index < m_size);
|
||||
|
||||
return m_data[index];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns a modifiable reference to the element at the given index.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
inline T& Array<T>::operator[] (size_t index)
|
||||
{
|
||||
CVF_TIGHT_ASSERT(this && m_data);
|
||||
CVF_TIGHT_ASSERT(index < m_size);
|
||||
|
||||
return m_data[index];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Assign (copy) the data in the given array
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
Array<T>& Array<T>::operator=(Array rhs)
|
||||
{
|
||||
CVF_TIGHT_ASSERT(!m_sharedData);
|
||||
|
||||
rhs.swap(*this);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Resize the array to the given size.
|
||||
/// The current contents (data) will be kept (as much as possible). Any new elements will be unassigned.
|
||||
/// Calling resize(0) is the same as clear().
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void Array<T>::resize(size_t size)
|
||||
{
|
||||
CVF_ASSERT(!m_sharedData);
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
if (m_data)
|
||||
{
|
||||
// Copy old data
|
||||
T* pTmp = m_data;
|
||||
m_data = new T[size];
|
||||
|
||||
size_t numToCopy = CVF_MIN(size, m_size);
|
||||
cvf::System::memcpy(m_data, size*sizeof(T), pTmp, numToCopy*sizeof(T));
|
||||
|
||||
delete[] pTmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_data = new T[size];
|
||||
}
|
||||
|
||||
m_size = size;
|
||||
m_capacity = size;
|
||||
}
|
||||
else
|
||||
{
|
||||
clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Clear the array, freeing all memory (if not shared) and setting capacity and size to zero.
|
||||
/// If the array was in shared mode, it will not be in shared mode anymore.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void Array<T>::clear()
|
||||
{
|
||||
if (!m_sharedData)
|
||||
{
|
||||
delete[] m_data;
|
||||
}
|
||||
|
||||
ground();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns the number of elements in the array
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
inline size_t Array<T>::size() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set the element at the given index. Index must be < size()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
inline void Array<T>::set(size_t index, const T& val)
|
||||
{
|
||||
CVF_TIGHT_ASSERT(index < m_size);
|
||||
|
||||
m_data[index] = val;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set all elements in the array to the given value
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
inline void Array<T>::setAll(const T& val)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < m_size; i++)
|
||||
{
|
||||
set(i, val);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Assign consecutive values to the elements in the array
|
||||
///
|
||||
/// Example: setConsecutive(2) on an array with size=3 gives: {2,3,4}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void Array<T>::setConsecutive(const T& startValue)
|
||||
{
|
||||
T val = startValue;
|
||||
size_t i;
|
||||
for (i = 0; i < m_size; i++)
|
||||
{
|
||||
set(i, val++);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns a const reference to the element at the given index
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
const T& cvf::Array<T>::get(size_t index) const
|
||||
{
|
||||
CVF_TIGHT_ASSERT(index < m_size);
|
||||
return m_data[index];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
T cvf::Array<T>::val(size_t index) const
|
||||
{
|
||||
CVF_TIGHT_ASSERT(index < m_size);
|
||||
return m_data[index];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns a const native pointer to the array storing the data
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
inline const T* Array<T>::ptr() const
|
||||
{
|
||||
CVF_TIGHT_ASSERT(this);
|
||||
return m_data;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns the native pointer to the array storing the data
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
inline T* Array<T>::ptr()
|
||||
{
|
||||
CVF_TIGHT_ASSERT(this);
|
||||
return m_data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns a const native pointer to the array storing the data
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
inline const T* Array<T>::ptr(size_t index) const
|
||||
{
|
||||
CVF_TIGHT_ASSERT(this);
|
||||
CVF_TIGHT_ASSERT(index < m_size);
|
||||
|
||||
return &m_data[index];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns the native pointer to the array storing the data
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
inline T* Array<T>::ptr(size_t index)
|
||||
{
|
||||
CVF_TIGHT_ASSERT(this);
|
||||
CVF_TIGHT_ASSERT(index < m_size);
|
||||
|
||||
return &m_data[index];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Data shared with another class. Will not delete on destruction.
|
||||
///
|
||||
/// Any method that reallocates data (resize, assign & setPtr) is not allowed and will assert
|
||||
/// The only way to break the shared 'connection' is via clear()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void Array<T>::setSharedPtr(T* data, size_t size)
|
||||
{
|
||||
CVF_ASSERT((data && size > 0) || (!data && size == 0));
|
||||
|
||||
clear();
|
||||
|
||||
m_data = data;
|
||||
m_size = size;
|
||||
m_sharedData = true;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set the data in the array to use the passed array.
|
||||
///
|
||||
/// This class takes ownership of the passed data.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void Array<T>::setPtr(T* data, size_t size)
|
||||
{
|
||||
CVF_ASSERT((data && size > 0) || (!data && size == 0));
|
||||
|
||||
// Not allowed
|
||||
// The only way to break the shared 'connection' is via clear()
|
||||
CVF_ASSERT(!m_sharedData);
|
||||
|
||||
clear();
|
||||
|
||||
m_data = data;
|
||||
m_size = size;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Delete any current data and set from the given data pointer
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void Array<T>::assign(const T* data, size_t size)
|
||||
{
|
||||
CVF_ASSERT(data);
|
||||
CVF_ASSERT(size > 0);
|
||||
CVF_ASSERT(!m_sharedData);
|
||||
|
||||
clear();
|
||||
resize(size);
|
||||
|
||||
// copy
|
||||
cvf::System::memcpy(m_data, m_size*sizeof(T), data, size*sizeof(T));
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Delete any current data and set from the given data
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void Array<T>::assign(const std::vector<T>& data)
|
||||
{
|
||||
CVF_ASSERT(!m_sharedData);
|
||||
|
||||
clear();
|
||||
|
||||
size_t newSize = data.size();
|
||||
if (newSize > 0)
|
||||
{
|
||||
resize(newSize);
|
||||
|
||||
cvf::System::memcpy(m_data, m_size*sizeof(T), &data[0], newSize*sizeof(T));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Copy data into the array
|
||||
///
|
||||
/// \warning Must have enough room for the new data, meaning the array must be resize()'ed before use
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void Array<T>::copyData(const T* pSource, size_t numElementsToCopy, size_t destIndex)
|
||||
{
|
||||
CVF_ASSERT(pSource);
|
||||
CVF_ASSERT(numElementsToCopy > 0);
|
||||
CVF_ASSERT(destIndex < m_size);
|
||||
CVF_ASSERT(destIndex + numElementsToCopy <= m_size);
|
||||
|
||||
cvf::System::memcpy(m_data + destIndex, (m_size - destIndex)*sizeof(T), pSource, numElementsToCopy*sizeof(T));
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Copy data into the array
|
||||
///
|
||||
/// \warning Must have enough room for the new data, meaning the array must be resize()'ed before use
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void Array<T>::copyData(const Array<T>& source, size_t numElementsToCopy, size_t destIndex, size_t sourceIndex)
|
||||
{
|
||||
CVF_ASSERT(numElementsToCopy > 0);
|
||||
CVF_ASSERT(destIndex < m_size);
|
||||
CVF_ASSERT(numElementsToCopy + destIndex <= m_size);
|
||||
|
||||
cvf::System::memcpy(m_data + destIndex, (m_size - destIndex)*sizeof(T), source.ptr() + sourceIndex, numElementsToCopy*sizeof(T));
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Copy data into this array with conversion.
|
||||
/// Data in source array will be converted using static_cast
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
template <typename U>
|
||||
void Array<T>::copyConvertedData(const Array<U>& source, size_t numElementsToCopy, size_t destIndex, size_t sourceIndex)
|
||||
{
|
||||
CVF_ASSERT(numElementsToCopy > 0);
|
||||
CVF_ASSERT(destIndex < m_size);
|
||||
CVF_ASSERT(numElementsToCopy + destIndex <= m_size);
|
||||
|
||||
size_t dst = destIndex;
|
||||
|
||||
size_t i;
|
||||
for (i = sourceIndex; i < sourceIndex + numElementsToCopy; i++)
|
||||
{
|
||||
m_data[dst++] = static_cast<T>(source[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns an array containing the specified elements
|
||||
///
|
||||
/// Example:
|
||||
/// <PRE>
|
||||
/// this = {2.0, 5.5, 100.0}
|
||||
/// elementIndices = { 0, 2, 1, 0, 2}
|
||||
/// -> output = {2.0, 100.0, 5.5, 2.0, 100.0}
|
||||
/// </PRE>
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
template <typename U>
|
||||
ref<Array<T> > Array<T>::extractElements(const Array<U>& elementIndices) const
|
||||
{
|
||||
ref<Array<T> > arr = new Array<T>;
|
||||
size_t numItems = elementIndices.size();
|
||||
|
||||
if (numItems > 0)
|
||||
{
|
||||
arr->resize(numItems);
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < numItems; i++)
|
||||
{
|
||||
U idx = elementIndices[i];
|
||||
arr->set(i, get(idx));
|
||||
}
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Copy the contents of the array to the given std::vector
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void Array<T>::toStdVector(std::vector<T>* vec) const
|
||||
{
|
||||
CVF_ASSERT(vec);
|
||||
|
||||
size_t numItems = size();
|
||||
vec->resize(numItems);
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < numItems; i++)
|
||||
{
|
||||
(*vec)[i] = (*this)[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the current capacity of the array (the size of the buffer). This will return a number >= size(),
|
||||
/// depending on if reserve() has been used or not.
|
||||
/// If capacity() > size(), then add() is allowed on the array.
|
||||
///
|
||||
/// \sa
|
||||
/// - reserve()
|
||||
/// - add()
|
||||
/// - squeeze()
|
||||
/// - setSizeZero()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
size_t Array<T>::capacity() const
|
||||
{
|
||||
return m_capacity;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Reserve (allocate) at least the given number of items.
|
||||
/// If capacity is less than the current buffer, nothing is done.
|
||||
/// size() of the array is not changed.
|
||||
///
|
||||
/// \sa
|
||||
/// - capacity()
|
||||
/// - add()
|
||||
/// - squeeze()
|
||||
/// - setSizeZero()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void Array<T>::reserve(size_t capacity)
|
||||
{
|
||||
CVF_ASSERT(!m_sharedData);
|
||||
|
||||
if ((capacity <= m_size) || (capacity <= m_capacity))
|
||||
{
|
||||
// Required capacity is less than current capacity, done!
|
||||
return;
|
||||
}
|
||||
|
||||
CVF_ASSERT(capacity > 0);
|
||||
CVF_ASSERT(capacity > m_size);
|
||||
|
||||
if (m_data)
|
||||
{
|
||||
// Copy old data
|
||||
T* pTmp = m_data;
|
||||
m_data = new T[capacity];
|
||||
m_capacity = capacity;
|
||||
|
||||
cvf::System::memcpy(m_data, capacity*sizeof(T), pTmp, m_size*sizeof(T));
|
||||
|
||||
delete[] pTmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
// alloc
|
||||
m_data = new T[capacity];
|
||||
m_capacity = capacity;
|
||||
}
|
||||
|
||||
CVF_ASSERT(m_size <= m_capacity);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Realloc the array to the current size(). Removing any reserved memory created by reserve().
|
||||
///
|
||||
/// \sa
|
||||
/// - reserve()
|
||||
/// - capacity()
|
||||
/// - add()
|
||||
/// - setSizeZero()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void Array<T>::squeeze()
|
||||
{
|
||||
CVF_ASSERT(!m_sharedData);
|
||||
|
||||
if (m_data && (m_size < m_capacity))
|
||||
{
|
||||
if (m_size > 0)
|
||||
{
|
||||
// Copy old data
|
||||
T* pTmp = m_data;
|
||||
m_data = new T[m_size];
|
||||
|
||||
cvf::System::memcpy(m_data, m_capacity*sizeof(T), pTmp, m_size*sizeof(T));
|
||||
|
||||
delete[] pTmp;
|
||||
|
||||
m_capacity = m_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set the size (number of items) in the array to zero, but keep the buffer. Items in the buffer
|
||||
/// are not modified.
|
||||
///
|
||||
/// \sa
|
||||
/// - reserve()
|
||||
/// - capacity()
|
||||
/// - add()
|
||||
/// - squeeze()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void Array<T>::setSizeZero()
|
||||
{
|
||||
CVF_TIGHT_ASSERT(!m_sharedData);
|
||||
|
||||
m_size = 0;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Add an item to the array.
|
||||
///
|
||||
/// Note that this will not grow the array, so the array needs to be pre-allocated with reserve()
|
||||
/// before calling this method. The method will assert if not enough space.
|
||||
///
|
||||
/// \sa
|
||||
/// - reserve()
|
||||
/// - capacity()
|
||||
/// - squeeze()
|
||||
/// - setSizeZero()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
inline void Array<T>::add(const T& val)
|
||||
{
|
||||
CVF_TIGHT_ASSERT(!m_sharedData);
|
||||
CVF_TIGHT_ASSERT(m_size < m_capacity);
|
||||
|
||||
m_data[m_size] = val;
|
||||
m_size++;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the min value and optionally the index of the (first) min value
|
||||
/// Works only on arrays with types that implement comparison operators
|
||||
/// Empty arrays will return std::numeric_limits<T>::max() and not modify index
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
T Array<T>::min(size_t* index) const
|
||||
{
|
||||
T minVal = std::numeric_limits<T>::max();
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < m_size; i++)
|
||||
{
|
||||
if (m_data[i] < minVal)
|
||||
{
|
||||
minVal = m_data[i];
|
||||
|
||||
if (index)
|
||||
{
|
||||
*index = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return minVal;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the min value and optionally the index of the (first) min value
|
||||
/// Works only on arrays with types that implement comparison operators
|
||||
/// Empty arrays will return std::numeric_limits<T>::max() and not modify index
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
T Array<T>::max(size_t* index) const
|
||||
{
|
||||
T maxVal = std::numeric_limits<T>::min();
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < m_size; i++)
|
||||
{
|
||||
if (m_data[i] > maxVal)
|
||||
{
|
||||
maxVal = m_data[i];
|
||||
|
||||
if (index)
|
||||
{
|
||||
*index = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return maxVal;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Exchanges the contents of the two arrays.
|
||||
///
|
||||
/// \param other Modifiable reference to the array that should have its contents swapped.
|
||||
///
|
||||
/// \warning Note that signature differs from normal CeeVizFramework practice. This is done to be
|
||||
/// consistent with the signature of std::swap()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void Array<T>::swap(Array& other)
|
||||
{
|
||||
using std::swap;
|
||||
|
||||
swap(m_size, other.m_size);
|
||||
swap(m_capacity, other.m_capacity);
|
||||
swap(m_data, other.m_data);
|
||||
swap(m_sharedData, other.m_sharedData);
|
||||
}
|
||||
|
||||
} // namespace cvf
|
||||
@@ -0,0 +1,462 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfAssert.h"
|
||||
#include "cvfSystem.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 4668)
|
||||
#include <windows.h>
|
||||
#pragma warning (pop)
|
||||
#include <io.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
// User actions (interactive responses)
|
||||
static const int USERACTION_CONTINUE = 0;
|
||||
static const int USERACTION_DEBUGBREAK = 1;
|
||||
static const int USERACTION_ABORT = 2;
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::AssertHandler
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// Base class for assert handlers
|
||||
///
|
||||
//==================================================================================================
|
||||
class AssertHandler
|
||||
{
|
||||
public:
|
||||
virtual ~AssertHandler() {}
|
||||
virtual Assert::FailAction handleAssert(const char* fileName, int lineNumber, const char* expr, const char* msg) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::AssertHandlerConsole
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// Assert handler for basic assert output to console
|
||||
///
|
||||
//==================================================================================================
|
||||
class AssertHandlerConsole : public AssertHandler
|
||||
{
|
||||
public:
|
||||
virtual Assert::FailAction handleAssert(const char* fileName, int lineNumber, const char* expr, const char* msg);
|
||||
|
||||
private:
|
||||
static void reportToConsole(const char* fileName, int lineNumber, const char* expr, const char* msg);
|
||||
static int askForUserActionUsingConsole();
|
||||
#ifdef WIN32
|
||||
static void winCreateConsoleAndRedirectIO(bool redirectInput);
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Show report of a failed assert in console and abort execution
|
||||
///
|
||||
/// On Windows, a console will be created if one doesn't exist (GUI applications)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Assert::FailAction AssertHandlerConsole::handleAssert(const char* fileName, int lineNumber, const char* expr, const char* msg)
|
||||
{
|
||||
// Just shows assert message in console.
|
||||
// Does the job on both Windows and Linux (creates a console on Windows if one doesn't exist)
|
||||
reportToConsole(fileName, lineNumber, expr, msg);
|
||||
|
||||
abort();
|
||||
|
||||
// Shouldn't really matter since we always abort
|
||||
return Assert::CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void AssertHandlerConsole::reportToConsole(const char* fileName, int lineNumber, const char* expr, const char* msg)
|
||||
{
|
||||
#ifdef WIN32
|
||||
// Make sure we have a console (applicable to Windows GUI applications)
|
||||
winCreateConsoleAndRedirectIO(false);
|
||||
#endif
|
||||
|
||||
std::cerr << "Assertion failed:";
|
||||
|
||||
if (expr)
|
||||
{
|
||||
std::cerr << " (" << expr << ")";
|
||||
}
|
||||
|
||||
if (msg)
|
||||
{
|
||||
std::cerr << " '" << msg << "'";
|
||||
}
|
||||
|
||||
if (expr || msg)
|
||||
{
|
||||
std::cerr << ",";
|
||||
}
|
||||
|
||||
std::cerr << " file " << fileName << ", line " << lineNumber << std::endl;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Ask for user action using console input
|
||||
///
|
||||
/// \return One of the USERACTION_ constants
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int AssertHandlerConsole::askForUserActionUsingConsole()
|
||||
{
|
||||
#ifdef WIN32
|
||||
// Make sure we have a console (applicable to Windows GUI applications)
|
||||
// Also ensures that input is redirected
|
||||
winCreateConsoleAndRedirectIO(true);
|
||||
#endif
|
||||
|
||||
// Let abort be the default choice
|
||||
#ifdef WIN32
|
||||
std::cerr << "Choose action: [A]bort, [R]etry (debug) or [I]gnore: default [A]\n";
|
||||
#else
|
||||
std::cerr << "Choose action: [A]bort or [I]gnore: default [A]\n";
|
||||
#endif
|
||||
|
||||
// Reset failstate, just in case.
|
||||
std::cin.clear();
|
||||
|
||||
std::string line;
|
||||
while (std::getline(std::cin, line))
|
||||
{
|
||||
int ch = 0;
|
||||
if (!std::cin.fail() && line.length() == 1)
|
||||
{
|
||||
ch = tolower(line[0]);
|
||||
}
|
||||
|
||||
if (ch == 'i')
|
||||
{
|
||||
return USERACTION_CONTINUE;
|
||||
}
|
||||
#ifdef WIN32
|
||||
else if (ch == 'r')
|
||||
{
|
||||
return USERACTION_DEBUGBREAK;
|
||||
}
|
||||
#endif
|
||||
else if (ch == 'a' || line.length() == 0)
|
||||
{
|
||||
return USERACTION_ABORT;
|
||||
}
|
||||
}
|
||||
|
||||
return USERACTION_ABORT;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Creates a console and redirects I/O from/to it (Windows only)
|
||||
///
|
||||
/// \param redirectInput If true, input will also be redirected.
|
||||
///
|
||||
/// Function is useful for Windows GUI applications. Allocates a console if it doesn't exist and
|
||||
/// then redirects output to the console. Also redirects input if \a redirectInput is true
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#ifdef WIN32
|
||||
void AssertHandlerConsole::winCreateConsoleAndRedirectIO(bool redirectInput)
|
||||
{
|
||||
// Allocate a new console for this app
|
||||
// Only one console can be associated with an app, so should fail if a console is already present.
|
||||
AllocConsole();
|
||||
|
||||
|
||||
bool redirStdOut = true;
|
||||
bool redirStdErr = true;
|
||||
bool redirStdIn = redirectInput;
|
||||
|
||||
if (redirStdOut)
|
||||
{
|
||||
HANDLE stdHandle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
int fileDescriptor = _open_osfhandle((intptr_t)stdHandle, _O_TEXT);
|
||||
FILE* fp = _fdopen(fileDescriptor, "w");
|
||||
|
||||
*stdout = *fp;
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
}
|
||||
|
||||
if (redirStdErr)
|
||||
{
|
||||
HANDLE stdHandle = GetStdHandle(STD_ERROR_HANDLE);
|
||||
int fileDescriptor = _open_osfhandle((intptr_t)stdHandle, _O_TEXT);
|
||||
FILE* fp = _fdopen(fileDescriptor, "w");
|
||||
|
||||
*stderr = *fp;
|
||||
setvbuf(stderr, NULL, _IONBF, 0);
|
||||
}
|
||||
|
||||
if (redirStdIn)
|
||||
{
|
||||
HANDLE stdHandle = GetStdHandle(STD_INPUT_HANDLE);
|
||||
int fileDescriptor = _open_osfhandle((intptr_t)stdHandle, _O_TEXT);
|
||||
FILE* fp = _fdopen(fileDescriptor, "r");
|
||||
|
||||
*stdin = *fp;
|
||||
setvbuf(stdin, NULL, _IONBF, 0);
|
||||
}
|
||||
|
||||
|
||||
// Make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog point to console as well
|
||||
std::ios::sync_with_stdio();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::AssertHandlerWinDialog
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// Assert handler for Windows, using a dialog with interaction
|
||||
///
|
||||
//==================================================================================================
|
||||
#ifdef WIN32
|
||||
class AssertHandlerWinDialog : public AssertHandler
|
||||
{
|
||||
public:
|
||||
virtual Assert::FailAction handleAssert(const char* fileName, int lineNumber, const char* expr, const char* msg);
|
||||
|
||||
private:
|
||||
static int handleUsingDialog(const char* fileName, int lineNumber, const char* expr, const char* msg);
|
||||
#ifdef _DEBUG
|
||||
static int handleUsingCrtDbgReport(const char* fileName, int lineNumber, const char* expr, const char* msg);
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#ifdef WIN32
|
||||
Assert::FailAction AssertHandlerWinDialog::handleAssert(const char* fileName, int lineNumber, const char* expr, const char* msg)
|
||||
{
|
||||
//int retVal = handleUsingCrtDbgReport(fileName, lineNumber, expr, msg);
|
||||
int retVal = handleUsingDialog(fileName, lineNumber, expr, msg);
|
||||
|
||||
if (retVal == USERACTION_CONTINUE)
|
||||
{
|
||||
return Assert::CONTINUE;
|
||||
}
|
||||
else if (retVal == USERACTION_DEBUGBREAK)
|
||||
{
|
||||
return Assert::DEBUGBREAK;
|
||||
}
|
||||
else if (retVal == USERACTION_ABORT)
|
||||
{
|
||||
// From __crtMessageWindow() in response to user clicking abort button
|
||||
// Note that it is better NOT to call abort() here, because the default implementation of abort() will call Watson
|
||||
// raise abort signal
|
||||
raise(SIGABRT);
|
||||
|
||||
// We usually won't get here, but it's possible that SIGABRT was ignored.
|
||||
// So exit the program anyway.
|
||||
_exit(3);
|
||||
}
|
||||
|
||||
// Shouldn't be getting here
|
||||
abort();
|
||||
return Assert::CONTINUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Shows message in interactive dialog and lets user choose how to proceed
|
||||
///
|
||||
/// \return Returns one of the USERACTION_ constants depending on which button the user chooses.
|
||||
///
|
||||
/// Compared to the handleUsingCrtDbgReport() function, this function will also work in release builds
|
||||
/// As opposed to the handleUsingCrtDbgReport(), this function will not call abort, but will return
|
||||
/// USERACTION_ABORT instead.
|
||||
///
|
||||
/// \todo Must add code to handle case where new assert is triggered while handling an assert
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#ifdef WIN32
|
||||
int AssertHandlerWinDialog::handleUsingDialog(const char* fileName, int lineNumber, const char* expr, const char* msg)
|
||||
{
|
||||
char szMsgBuf[2048];
|
||||
|
||||
System::strcpy(szMsgBuf, sizeof(szMsgBuf), "Assertion failed\n");
|
||||
|
||||
System::strcat(szMsgBuf, sizeof(szMsgBuf), "\nFile: ");
|
||||
if (fileName)
|
||||
{
|
||||
System::strcat(szMsgBuf, sizeof(szMsgBuf), fileName);
|
||||
}
|
||||
|
||||
System::strcat(szMsgBuf, sizeof(szMsgBuf), "\nLine: ");
|
||||
if (lineNumber >= 0)
|
||||
{
|
||||
char szLinNumBuf[20];
|
||||
System::sprintf(szLinNumBuf, sizeof(szLinNumBuf), "%d", lineNumber);
|
||||
System::strcat(szMsgBuf, sizeof(szMsgBuf), szLinNumBuf);
|
||||
}
|
||||
|
||||
|
||||
if (expr)
|
||||
{
|
||||
System::strcat(szMsgBuf, sizeof(szMsgBuf), "\n\n");
|
||||
System::strcat(szMsgBuf, sizeof(szMsgBuf), "Expression: ");
|
||||
System::strcat(szMsgBuf, sizeof(szMsgBuf), expr);
|
||||
}
|
||||
|
||||
if (msg)
|
||||
{
|
||||
System::strcat(szMsgBuf, sizeof(szMsgBuf), "\n\n");
|
||||
System::strcat(szMsgBuf, sizeof(szMsgBuf), msg);
|
||||
}
|
||||
|
||||
System::strcat(szMsgBuf, sizeof(szMsgBuf), "\n\n(Press Retry to debug application)");
|
||||
|
||||
|
||||
int retVal = ::MessageBoxA(NULL, szMsgBuf, "Assertion Failed", MB_TASKMODAL|MB_ICONHAND|MB_ABORTRETRYIGNORE|MB_SETFOREGROUND);
|
||||
|
||||
if (retVal == IDIGNORE) return USERACTION_CONTINUE;
|
||||
else if (retVal == IDRETRY) return USERACTION_DEBUGBREAK;
|
||||
else return USERACTION_ABORT;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Wrapper function for the CRT _CrtDbgReport() function
|
||||
///
|
||||
/// This function never returns if the user chooses 'Abort'
|
||||
/// Note that the underlying function is only available in debug builds
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#if defined WIN32 && defined _DEBUG
|
||||
int AssertHandlerWinDialog::handleUsingCrtDbgReport(const char* fileName, int lineNumber, const char* expr, const char* msg)
|
||||
{
|
||||
// Create message combining expression and message
|
||||
char szMsgBuf[2048];
|
||||
szMsgBuf[0] = '\0';
|
||||
|
||||
if (expr)
|
||||
{
|
||||
System::strcat(szMsgBuf, sizeof(szMsgBuf), expr);
|
||||
}
|
||||
|
||||
if (msg)
|
||||
{
|
||||
System::strcat(szMsgBuf, sizeof(szMsgBuf), "\n");
|
||||
System::strcat(szMsgBuf, sizeof(szMsgBuf), msg);
|
||||
}
|
||||
|
||||
int retVal = _CrtDbgReport(_CRT_ASSERT, fileName, lineNumber, NULL, szMsgBuf);
|
||||
|
||||
if (retVal == 0) return USERACTION_CONTINUE;
|
||||
else if (retVal == 1) return USERACTION_DEBUGBREAK;
|
||||
else return USERACTION_ABORT;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::Assert
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// Helper class to customize assert
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
#ifdef WIN32
|
||||
AssertHandler* Assert::sm_handler = new AssertHandlerWinDialog;
|
||||
#else
|
||||
AssertHandler* Assert::sm_handler = new AssertHandlerConsole;
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void Assert::setReportMode(ReportMode reportMode)
|
||||
{
|
||||
#ifndef WIN32
|
||||
if (reportMode == INTERACTIVE_DIALOG) return;
|
||||
#endif
|
||||
|
||||
delete sm_handler;
|
||||
sm_handler = NULL;
|
||||
|
||||
if (reportMode == CONSOLE)
|
||||
{
|
||||
sm_handler = new AssertHandlerConsole;
|
||||
}
|
||||
#ifdef WIN32
|
||||
else if (reportMode == INTERACTIVE_DIALOG)
|
||||
{
|
||||
sm_handler = new AssertHandlerWinDialog;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Show report of a failed assert
|
||||
///
|
||||
/// If assertions are configured to be interactive, a message box will be shown on Windows and
|
||||
/// the user may opt to ignore or trigger debugging.
|
||||
/// On Linux, or if interactive asserts are disabled, the application will terminate.
|
||||
///
|
||||
/// \todo Add handling of cases where we get another assert while processing the first one AND
|
||||
/// asserts from multiple threads.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Assert::FailAction Assert::reportFailedAssert(const char* fileName, int lineNumber, const char* expr, const char* msg)
|
||||
{
|
||||
if (sm_handler)
|
||||
{
|
||||
return sm_handler->handleAssert(fileName, lineNumber, expr, msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
abort();
|
||||
return CONTINUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace cvf
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace cvf {
|
||||
|
||||
// Forward of base class for assert handlers
|
||||
class AssertHandler;
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Helper class to customize assert behavior
|
||||
//
|
||||
//==================================================================================================
|
||||
class Assert
|
||||
{
|
||||
public:
|
||||
enum ReportMode
|
||||
{
|
||||
CONSOLE, // Report asserts to console only and then abort. (default mode for Linux)
|
||||
INTERACTIVE_DIALOG // Show message in dialog and ask for user action (Windows only, default mode on Windows)
|
||||
};
|
||||
|
||||
enum FailAction
|
||||
{
|
||||
CONTINUE, // Continue execution
|
||||
DEBUGBREAK // Execution should be stopped and debugger should be triggered (currently windows only)
|
||||
};
|
||||
|
||||
public:
|
||||
static void setReportMode(ReportMode reportMode);
|
||||
static FailAction reportFailedAssert(const char* fileName, int lineNumber, const char* expr, const char* msg);
|
||||
|
||||
private:
|
||||
static AssertHandler* sm_handler;
|
||||
};
|
||||
|
||||
} // cvf
|
||||
|
||||
|
||||
|
||||
// Define to trigger debug trap for use with assert macros
|
||||
// Currently only useful and in action on windows
|
||||
#ifdef WIN32
|
||||
#define CVF_DEBUGTRAP() __debugbreak()
|
||||
#else
|
||||
#define CVF_DEBUGTRAP() ((void)0)
|
||||
#endif
|
||||
|
||||
|
||||
// Define our assert macros
|
||||
#if CVF_ENABLE_ASSERTS == 1
|
||||
# define CVF_ASSERT(expr) (void)( (!!(expr)) || (cvf::Assert::CONTINUE == cvf::Assert::reportFailedAssert(__FILE__, __LINE__, #expr, NULL)) || (CVF_DEBUGTRAP(), 0) )
|
||||
# define CVF_ASSERT_MSG(expr, msg) (void)( (!!(expr)) || (cvf::Assert::CONTINUE == cvf::Assert::reportFailedAssert(__FILE__, __LINE__, #expr, (msg))) || (CVF_DEBUGTRAP(), 0) )
|
||||
# define CVF_FAIL_MSG(msg) (void)( (cvf::Assert::CONTINUE == cvf::Assert::reportFailedAssert(__FILE__, __LINE__, NULL, (msg))) || (CVF_DEBUGTRAP(), 0) )
|
||||
#else
|
||||
# define CVF_ASSERT(expr) ((void)0)
|
||||
# define CVF_ASSERT_MSG(expr, msg) ((void)0)
|
||||
# define CVF_FAIL_MSG(msg) ((void)0)
|
||||
#endif
|
||||
|
||||
#if CVF_ENABLE_TIGHT_ASSERTS == 1 && CVF_ENABLE_ASSERTS == 1
|
||||
# define CVF_TIGHT_ASSERT(expr) CVF_ASSERT(expr)
|
||||
# define CVF_TIGHT_ASSERT_MSG(expr, msg) CVF_ASSERT_MSG(expr, msg)
|
||||
#else
|
||||
# define CVF_TIGHT_ASSERT(expr) ((void)0)
|
||||
# define CVF_TIGHT_ASSERT_MSG(expr, msg) ((void)0)
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(WIN32) && !defined(CVF_LINUX) && !defined(CVF_IOS) && !defined(CVF_OSX)
|
||||
#error No platform defined
|
||||
#endif
|
||||
|
||||
// Global include file with definitions useful for all CeeVizFramework files
|
||||
|
||||
// Disable some annoying warnings so we can compile with warning level Wall
|
||||
#ifdef WIN32
|
||||
// 4512 'class' : assignment operator could not be generated : Due to problems with classes with reference member variables (e.g. VertexCompactor)
|
||||
// 4514 unreferenced inline/local function has been removed
|
||||
// 4625 copy constructor could not be generated because a base class copy constructor is inaccessible
|
||||
// 4626 assignment operator could not be generated because a base class assignment operator is inaccessible
|
||||
// 4640 'staticInstance' : construction of local static object is not thread-safe -> used by singletons. To be revisited.
|
||||
// 4710 function 'func_name' not inlined
|
||||
// 4711 function 'func_name' selected for automatic inline expansion
|
||||
// 4738 storing 32-bit float result in memory, possible loss of performance
|
||||
// 4820 'bytes' bytes padding added after construct 'member_name'
|
||||
// 4986 'operator new[]': exception specification does not match previous declaration
|
||||
#pragma warning (disable: 4512 4514 4625 4626 4640 4710 4711 4738 4820 4986)
|
||||
#endif
|
||||
|
||||
// Helper macro to disable (ignore) compiler warnings on GCC
|
||||
// The needed pragma is only available in GCC for versions 4.2.x and above
|
||||
#if defined __GNUC__ && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 402)
|
||||
#define CVF_DO_PRAGMA(x) _Pragma(#x)
|
||||
#define CVF_GCC_DIAGNOSTIC_IGNORE(OPTION_STRING) CVF_DO_PRAGMA(GCC diagnostic ignored OPTION_STRING)
|
||||
#else
|
||||
#define CVF_GCC_DIAGNOSTIC_IGNORE(OPTION_STRING)
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(CVF_LINUX) || defined(CVF_IOS) || defined(CVF_OSX)
|
||||
// Used by int64_t on *nix below
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
// Brings in size_t and definition of NULL
|
||||
#include <cstddef>
|
||||
|
||||
// Added due to conflict between std::min/max and define in Windows.h
|
||||
#define CVF_MIN(X, Y) ((X) < (Y) ? (X) : (Y))
|
||||
#define CVF_MAX(X, Y) ((X) > (Y) ? (X) : (Y))
|
||||
|
||||
// Macro for avoiding "unused parameter" warnings
|
||||
// The bottom one is the best alternative, but unfortunately doesn't work on VS2010
|
||||
#ifdef WIN32
|
||||
#define CVF_UNUSED(EXPR) (void)(EXPR);
|
||||
#else
|
||||
#define CVF_UNUSED(EXPR) (void)sizeof(EXPR);
|
||||
#endif
|
||||
|
||||
|
||||
// Macro to disable the copy constructor and assignment operator
|
||||
// Should be used in the private section of a class
|
||||
#define CVF_DISABLE_COPY_AND_ASSIGN(CLASS_NAME) \
|
||||
CLASS_NAME(const CLASS_NAME&); \
|
||||
void operator=(const CLASS_NAME&)
|
||||
|
||||
|
||||
/// Ceetron Visualization Framework namespace
|
||||
namespace cvf {
|
||||
|
||||
typedef unsigned char ubyte;
|
||||
typedef unsigned short ushort;
|
||||
typedef unsigned int uint;
|
||||
|
||||
// 64bit integer support via the int64 type
|
||||
#ifdef WIN32
|
||||
typedef __int64 int64;
|
||||
#elif defined(CVF_LINUX) || defined(CVF_IOS) || defined(CVF_OSX)
|
||||
typedef int64_t int64;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#include "cvfConfigCore.h"
|
||||
#include "cvfVersion.h"
|
||||
#include "cvfAssert.h"
|
||||
@@ -0,0 +1,208 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// CeeVizFramework
|
||||
// Lib: LibCore
|
||||
//
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Please see references below for copyright, usage rights and license for this file.
|
||||
//##################################################################################################
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfBase64.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning (disable: 4242 4244 4267 4365)
|
||||
#endif
|
||||
|
||||
CVF_GCC_DIAGNOSTIC_IGNORE("-Wconversion")
|
||||
CVF_GCC_DIAGNOSTIC_IGNORE("-Wunused-parameter")
|
||||
|
||||
#ifdef CVF_LINUX
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
|
||||
// Doxygen conditional section to hide contents of the cvf_base64 namespace
|
||||
/// \cond CVF_NEVER_INCLUDE
|
||||
|
||||
namespace cvf_base64
|
||||
{
|
||||
//## START -- base64.cpp
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// start include
|
||||
// base64.h
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
base64.cpp and base64.h
|
||||
|
||||
Copyright (C) 2004-2008 Rene Nyffenegger
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the author be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Rene Nyffenegger rene.nyffenegger@adp-gmbh.ch
|
||||
|
||||
*/
|
||||
|
||||
// Commented out by Ceetron
|
||||
//#include "base64.h"
|
||||
//#include <iostream>
|
||||
|
||||
static const std::string base64_chars =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
|
||||
|
||||
static inline bool is_base64(unsigned char c) {
|
||||
return (isalnum(c) || (c == '+') || (c == '/'));
|
||||
}
|
||||
|
||||
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
|
||||
std::string ret;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
unsigned char char_array_3[3];
|
||||
unsigned char char_array_4[4];
|
||||
|
||||
while (in_len--) {
|
||||
char_array_3[i++] = *(bytes_to_encode++);
|
||||
if (i == 3) {
|
||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||
|
||||
for(i = 0; (i <4) ; i++)
|
||||
ret += base64_chars[char_array_4[i]];
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i)
|
||||
{
|
||||
for(j = i; j < 3; j++)
|
||||
char_array_3[j] = '\0';
|
||||
|
||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||
|
||||
for (j = 0; (j < i + 1); j++)
|
||||
ret += base64_chars[char_array_4[j]];
|
||||
|
||||
while((i++ < 3))
|
||||
ret += '=';
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
std::string base64_decode(std::string const& encoded_string) {
|
||||
int in_len = encoded_string.size();
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int in_ = 0;
|
||||
unsigned char char_array_4[4], char_array_3[3];
|
||||
std::string ret;
|
||||
|
||||
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
|
||||
char_array_4[i++] = encoded_string[in_]; in_++;
|
||||
if (i ==4) {
|
||||
for (i = 0; i <4; i++)
|
||||
char_array_4[i] = base64_chars.find(char_array_4[i]);
|
||||
|
||||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||
|
||||
for (i = 0; (i < 3); i++)
|
||||
ret += char_array_3[i];
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i) {
|
||||
for (j = i; j <4; j++)
|
||||
char_array_4[j] = 0;
|
||||
|
||||
for (j = 0; j <4; j++)
|
||||
char_array_4[j] = base64_chars.find(char_array_4[j]);
|
||||
|
||||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||
|
||||
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
//## END -- base64.cpp
|
||||
|
||||
} // namespace cvf_base64
|
||||
|
||||
// End of Doxygen conditional section
|
||||
/// \endcond
|
||||
|
||||
|
||||
namespace cvf {
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::Base64
|
||||
/// \ingroup Core
|
||||
///
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Encode a binary buffer
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::string Base64::encode(const cvf::UByteArray& data)
|
||||
{
|
||||
return (data.size() > 0) ? cvf_base64::base64_encode(data.ptr(), data.size()) : "";
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Decode already encoded data. Array returned is NULL if unable to decode
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::ref<cvf::UByteArray> Base64::decode(const std::string& encodedData)
|
||||
{
|
||||
if (encodedData.size() < 1) return NULL;
|
||||
|
||||
std::string decodedData = cvf_base64::base64_decode(encodedData);
|
||||
size_t numDecodedBytes = decodedData.length();
|
||||
if (numDecodedBytes == 0) return NULL;
|
||||
|
||||
cvf::UByteArray* data = new cvf::UByteArray;
|
||||
data->resize(numDecodedBytes);
|
||||
data->copyData(reinterpret_cast<const unsigned char*>(decodedData.c_str()), numDecodedBytes, 0);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
} // namespace cvf
|
||||
@@ -0,0 +1,42 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfString.h"
|
||||
#include "cvfArray.h"
|
||||
|
||||
|
||||
namespace cvf {
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Base64 encoding and decoding for representing binary data in an ASCII string format by
|
||||
// translating it into a radix-64 representation.
|
||||
//
|
||||
//==================================================================================================
|
||||
class Base64
|
||||
{
|
||||
public:
|
||||
static std::string encode(const cvf::UByteArray& data);
|
||||
static cvf::ref<cvf::UByteArray> decode(const std::string& encodedData);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfCharArray.h"
|
||||
#include "cvfSystem.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::CharArray
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// 8 bit zero terminated char array.
|
||||
///
|
||||
/// Behind the scenes, the array always has a 0 termination sentinel.
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
CharArray::CharArray()
|
||||
{
|
||||
m_data.push_back('\0');
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
CharArray::CharArray(size_t size, char c)
|
||||
{
|
||||
resize(size);
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
m_data[i] = c;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
CharArray::CharArray(const char* str)
|
||||
{
|
||||
size_t numChars = System::strlen(str);
|
||||
resize(numChars);
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < numChars; i++)
|
||||
{
|
||||
m_data[i] = str[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
char& CharArray::operator[](size_t i)
|
||||
{
|
||||
CVF_TIGHT_ASSERT(i < m_data.size() - 1);
|
||||
|
||||
return m_data[i];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const char& CharArray::operator[](size_t i) const
|
||||
{
|
||||
CVF_TIGHT_ASSERT(i < m_data.size() - 1);
|
||||
|
||||
return m_data[i];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void CharArray::resize(size_t size)
|
||||
{
|
||||
m_data.resize(size + 1, '\0');
|
||||
m_data[size] = '\0';
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Add a character to the array. Array grows if necessary.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void CharArray::push_back(char c)
|
||||
{
|
||||
CVF_TIGHT_ASSERT(m_data.size() > 0);
|
||||
|
||||
m_data[m_data.size() - 1] = c;
|
||||
m_data.push_back('\0');
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the size of the character array.
|
||||
///
|
||||
/// Note that this is not necessarily the length of the contained string. In order to get the string
|
||||
/// length, you must call System::strlen().
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t CharArray::size() const
|
||||
{
|
||||
CVF_TIGHT_ASSERT(m_data.size() > 0);
|
||||
|
||||
return m_data.size() - 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get a const char* pointer to the string
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const char* CharArray::ptr() const
|
||||
{
|
||||
CVF_ASSERT(m_data.size() > 0);
|
||||
CVF_ASSERT(m_data[m_data.size() - 1] == '\0');
|
||||
|
||||
return &m_data[0];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get a const char* pointer to the string
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
char* CharArray::ptr()
|
||||
{
|
||||
CVF_ASSERT(m_data.size() > 0);
|
||||
CVF_ASSERT(m_data[m_data.size() - 1] == '\0');
|
||||
|
||||
return &m_data[0];
|
||||
}
|
||||
|
||||
|
||||
} // namespace cvf
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// 8 bit zero terminated char array
|
||||
//
|
||||
//==================================================================================================
|
||||
class CharArray
|
||||
{
|
||||
public:
|
||||
CharArray();
|
||||
CharArray(size_t size, char c);
|
||||
explicit CharArray(const char* str);
|
||||
|
||||
char& operator[](size_t i);
|
||||
const char& operator[](size_t i) const;
|
||||
|
||||
void resize(size_t size);
|
||||
void push_back(char c);
|
||||
size_t size() const;
|
||||
|
||||
const char* ptr() const;
|
||||
char* ptr();
|
||||
|
||||
private:
|
||||
std::vector<char> m_data;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfObject.h"
|
||||
#include "cvfMath.h"
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// A collection class for reference counted objects (that derive from Object)
|
||||
//
|
||||
//==================================================================================================
|
||||
template<typename T>
|
||||
class Collection
|
||||
{
|
||||
public:
|
||||
Collection();
|
||||
Collection(const Collection& other);
|
||||
explicit Collection(const std::vector< ref<T> >& vector);
|
||||
|
||||
Collection& operator=(Collection rhs);
|
||||
Collection& operator=(const std::vector< ref<T> >& vector);
|
||||
const ref<T>& operator[](size_t index) const;
|
||||
ref<T>& operator[](size_t index);
|
||||
|
||||
void push_back(T* data);
|
||||
const T* at(size_t index) const;
|
||||
T* at(size_t index);
|
||||
|
||||
void resize(size_t size);
|
||||
size_t size() const;
|
||||
void reserve(size_t capacity);
|
||||
size_t capacity() const;
|
||||
void clear();
|
||||
|
||||
bool empty() const;
|
||||
bool contains(const T* data) const;
|
||||
size_t indexOf(const T* data) const;
|
||||
|
||||
void erase(const T* data);
|
||||
void eraseAt(size_t index);
|
||||
|
||||
void swap(Collection& other);
|
||||
|
||||
// Iterator support
|
||||
public:
|
||||
typedef typename std::vector<ref<T> >::iterator iterator;
|
||||
typedef typename std::vector<ref<T> >::const_iterator const_iterator;
|
||||
|
||||
iterator begin();
|
||||
iterator end();
|
||||
const_iterator begin() const;
|
||||
const_iterator end() const;
|
||||
|
||||
private:
|
||||
std::vector<ref<T> > m_vector;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#include "cvfCollection.inl"
|
||||
@@ -0,0 +1,314 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::Collection
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// A collection class for reference counted objects (that derive from Object).
|
||||
///
|
||||
/// The class add a reference to all objects when added to the array, and releases them when removed
|
||||
/// from the array.
|
||||
///
|
||||
/// The class exposes the same public interface as a std::vector, so see the STL documentation
|
||||
/// for documentation on most of the methods.
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Default constructor. Create an empty collection
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
Collection<T>::Collection()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Copy constructor
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
Collection<T>::Collection(const Collection& other)
|
||||
: m_vector(other.m_vector)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Create a collection and copy the contents from the passed collection
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
Collection<T>::Collection(const std::vector< ref<T> >& vector)
|
||||
: m_vector(vector)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
Collection<T>& Collection<T>::operator=(Collection rhs)
|
||||
{
|
||||
rhs.swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set the collection to contain the same elements as the passed collection
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
Collection<T>& Collection<T>::operator=(const std::vector< ref<T> >& vector)
|
||||
{
|
||||
m_vector = vector;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
const ref<T>& Collection<T>::operator[](size_t index) const
|
||||
{
|
||||
return m_vector[index];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
ref<T>& Collection<T>::operator[](size_t index)
|
||||
{
|
||||
return m_vector[index];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void Collection<T>::push_back(T* data)
|
||||
{
|
||||
m_vector.push_back(data);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
const T* Collection<T>::at(size_t index) const
|
||||
{
|
||||
return m_vector[index].p();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
T* Collection<T>::at(size_t index)
|
||||
{
|
||||
return m_vector[index].p();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void Collection<T>::resize(size_t size)
|
||||
{
|
||||
m_vector.resize(size);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
size_t Collection<T>::size() const
|
||||
{
|
||||
return m_vector.size();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void Collection<T>::reserve(size_t capacity)
|
||||
{
|
||||
m_vector.reserve(capacity);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
size_t Collection<T>::capacity() const
|
||||
{
|
||||
return m_vector.capacity();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void Collection<T>::clear()
|
||||
{
|
||||
m_vector.clear();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
bool Collection<T>::empty() const
|
||||
{
|
||||
return m_vector.empty();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
bool Collection<T>::contains(const T* data) const
|
||||
{
|
||||
if (std::find(m_vector.begin(), m_vector.end(), data) != m_vector.end())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Find index of the first occurence of the specified element
|
||||
///
|
||||
/// Returns UNDEFINED_SIZE_T if element could not be found
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
size_t Collection<T>::indexOf(const T* data) const
|
||||
{
|
||||
typename std::vector<ref<T> >::const_iterator it = std::find(m_vector.begin(), m_vector.end(), data);
|
||||
if (it != m_vector.end())
|
||||
{
|
||||
return static_cast<size_t>(it - m_vector.begin());
|
||||
}
|
||||
else
|
||||
{
|
||||
return UNDEFINED_SIZE_T;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Erase the specified element
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void Collection<T>::erase(const T* data)
|
||||
{
|
||||
typename std::vector<ref<T> >::iterator it = std::find(m_vector.begin(), m_vector.end(), data);
|
||||
if (it != m_vector.end())
|
||||
{
|
||||
m_vector.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Erase the element at the specified index
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void Collection<T>::eraseAt(size_t index)
|
||||
{
|
||||
CVF_ASSERT(index < m_vector.size());
|
||||
|
||||
// Cast may have to be to std::vector<T>::difference_type
|
||||
m_vector.erase(m_vector.begin() + static_cast<ptrdiff_t>(index));
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void Collection<T>::swap(Collection& other)
|
||||
{
|
||||
m_vector.swap(other.m_vector);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Return iterator to beginning
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
typename Collection<T>::iterator Collection<T>::begin()
|
||||
{
|
||||
return m_vector.begin();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Return iterator to end
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
typename Collection<T>::iterator Collection<T>::end()
|
||||
{
|
||||
return m_vector.end();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Return const iterator to beginning
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
typename Collection<T>::const_iterator Collection<T>::begin() const
|
||||
{
|
||||
return m_vector.begin();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Return const iterator to end
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
typename Collection<T>::const_iterator Collection<T>::end() const
|
||||
{
|
||||
return m_vector.end();
|
||||
}
|
||||
|
||||
} // namespace cvf
|
||||
@@ -0,0 +1,532 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfColor3.h"
|
||||
#include "cvfMath.h"
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::Color3
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// Abstract base class for 3-component RGB colors.
|
||||
///
|
||||
/// Currently, this class only contains the ColorIdent enums,
|
||||
//==================================================================================================
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::Color3f
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// Class for storing and manipulating 3-component RGB floating point colors
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Default constructor, initializes all color components to 0.0
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color3f::Color3f()
|
||||
{
|
||||
m_rgb[0] = 0.0f;
|
||||
m_rgb[1] = 0.0f;
|
||||
m_rgb[2] = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color3f::Color3f(float r, float g, float b)
|
||||
{
|
||||
m_rgb[0] = r;
|
||||
m_rgb[1] = g;
|
||||
m_rgb[2] = b;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color3f::Color3f(const Color3f& other)
|
||||
{
|
||||
m_rgb[0] = other.m_rgb[0];
|
||||
m_rgb[1] = other.m_rgb[1];
|
||||
m_rgb[2] = other.m_rgb[2];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color3f::Color3f(ColorIdent colorIdent)
|
||||
{
|
||||
Color3ub byteColor(colorIdent);
|
||||
*this = Color3f::fromByteColor(byteColor.r(), byteColor.g(), byteColor.b());
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Explicit conversion constructor from byte color
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color3f::Color3f(const Color3ub& byteColor)
|
||||
{
|
||||
*this = Color3f::fromByteColor(byteColor.r(), byteColor.g(), byteColor.b());
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color3f& Color3f::operator=(const Color3f& rhs)
|
||||
{
|
||||
m_rgb[0] = rhs.m_rgb[0];
|
||||
m_rgb[1] = rhs.m_rgb[1];
|
||||
m_rgb[2] = rhs.m_rgb[2];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color3f& Color3f::operator=(ColorIdent colorIdent)
|
||||
{
|
||||
return operator=(Color3f(colorIdent));
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool Color3f::operator==(const Color3f& rhs) const
|
||||
{
|
||||
if (m_rgb[0] == rhs.m_rgb[0] &&
|
||||
m_rgb[1] == rhs.m_rgb[1] &&
|
||||
m_rgb[2] == rhs.m_rgb[2])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool Color3f::operator!=(const Color3f& rhs) const
|
||||
{
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns the red color component of this color
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
float Color3f::r() const
|
||||
{
|
||||
return m_rgb[0];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns the green color component of this color
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
float Color3f::g() const
|
||||
{
|
||||
return m_rgb[1];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns the blue color component of this color
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
float Color3f::b() const
|
||||
{
|
||||
return m_rgb[2];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get modifiable reference to the red color component.
|
||||
///
|
||||
/// Used for setting the color, e.g. <tt>r() = 0.5f</tt>
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
float& Color3f::r()
|
||||
{
|
||||
return m_rgb[0];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get modifiable reference to the green color component.
|
||||
///
|
||||
/// Used for setting the color, e.g. <tt>g() = 0.5f</tt>
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
float& Color3f::g()
|
||||
{
|
||||
return m_rgb[1];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get modifiable reference to the blue color component.
|
||||
///
|
||||
/// Used for setting the color, e.g. <tt>b() = 0.5f</tt>
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
float& Color3f::b()
|
||||
{
|
||||
return m_rgb[2];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Sets all color components
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void Color3f::set(float r, float g, float b)
|
||||
{
|
||||
m_rgb[0] = r;
|
||||
m_rgb[1] = g;
|
||||
m_rgb[2] = b;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Query whether this color is valid
|
||||
///
|
||||
/// For a color to be considered valid, all the component values must be in the range 0.0 to 1.0
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool Color3f::isValid() const
|
||||
{
|
||||
if (!Math::valueInRange(m_rgb[0], 0.0f, 1.0f)) return false;
|
||||
if (!Math::valueInRange(m_rgb[1], 0.0f, 1.0f)) return false;
|
||||
if (!Math::valueInRange(m_rgb[2], 0.0f, 1.0f)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const float* Color3f::ptr() const
|
||||
{
|
||||
return m_rgb;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get red component as byte color (unsigned char)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
unsigned char Color3f::rByte() const
|
||||
{
|
||||
int val = static_cast<int>(m_rgb[0]*255.0f + 0.5f);
|
||||
|
||||
if (val < 0) return 0;
|
||||
else if (val > 255) return 255;
|
||||
else return static_cast<unsigned char>(val);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get green component as byte color (unsigned char)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
unsigned char Color3f::gByte() const
|
||||
{
|
||||
int val = static_cast<int>(m_rgb[1]*255.0f + 0.5f);
|
||||
|
||||
if (val < 0) return 0;
|
||||
else if (val > 255) return 255;
|
||||
else return static_cast<unsigned char>(val);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get blue component as a byte color (unsigned char)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
unsigned char Color3f::bByte() const
|
||||
{
|
||||
int val = static_cast<int>(m_rgb[2]*255.0f + 0.5f);
|
||||
|
||||
if (val < 0) return 0;
|
||||
else if (val > 255) return 255;
|
||||
else return static_cast<unsigned char>(val);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Static function to construct a Color3f object from byte RGB values.
|
||||
///
|
||||
/// All the values parameter values should be in the range 0-255. The returned object will always
|
||||
/// have its components clamped to the range 0.0 to 1.0
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color3f Color3f::fromByteColor(ubyte r, ubyte g, ubyte b)
|
||||
{
|
||||
// Constructor sets all elements to 0
|
||||
Color3f c;
|
||||
|
||||
c.m_rgb[0] = static_cast<float>(r)/255.0f;
|
||||
c.m_rgb[1] = static_cast<float>(g)/255.0f;
|
||||
c.m_rgb[2] = static_cast<float>(b)/255.0f;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::Color3ub
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// Class for storing unsigned byte RGB colors
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Default constructor, initializes all color components to 0
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color3ub::Color3ub()
|
||||
{
|
||||
m_rgb[0] = 0;
|
||||
m_rgb[1] = 0;
|
||||
m_rgb[2] = 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Constructor with initialization of all components
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color3ub::Color3ub(ubyte r, ubyte g, ubyte b)
|
||||
{
|
||||
m_rgb[0] = r;
|
||||
m_rgb[1] = g;
|
||||
m_rgb[2] = b;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Copy constructor
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color3ub::Color3ub(const Color3ub& other)
|
||||
{
|
||||
m_rgb[0] = other.m_rgb[0];
|
||||
m_rgb[1] = other.m_rgb[1];
|
||||
m_rgb[2] = other.m_rgb[2];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color3ub::Color3ub(ColorIdent colorIdent)
|
||||
{
|
||||
switch (colorIdent)
|
||||
{
|
||||
case RED: set(255, 0, 0); break;
|
||||
case GREEN: set( 0, 255, 0); break;
|
||||
case BLUE: set( 0, 0, 255); break;
|
||||
case YELLOW: set(255, 255, 0); break;
|
||||
case CYAN: set( 0, 255, 255); break;
|
||||
case MAGENTA: set(255, 0, 255); break;
|
||||
|
||||
case WHITE: set(255, 255, 255); break;
|
||||
case BLACK: set( 0, 0, 0); break;
|
||||
case LIGHT_GRAY: set(192, 192, 192); break;
|
||||
case GRAY: set(128, 128, 128); break;
|
||||
case DARK_GRAY: set( 64, 64, 64); break;
|
||||
|
||||
case BROWN: set(165, 42, 42); break;
|
||||
case CRIMSON: set(220, 20, 60); break;
|
||||
case DARK_BLUE: set( 0, 0, 139); break;
|
||||
case DARK_YELLOW: set(139, 139, 0); break;
|
||||
case DARK_CYAN: set( 0, 139, 139); break;
|
||||
case DARK_GREEN: set( 0, 100, 0); break;
|
||||
case DARK_MAGENTA: set(139, 0, 139); break;
|
||||
case DARK_ORANGE: set(255, 140, 0); break;
|
||||
case DARK_RED: set(139, 0, 0); break;
|
||||
case DARK_VIOLET: set(148, 0, 211); break;
|
||||
case DEEP_PINK: set(255, 20, 147); break;
|
||||
case FOREST_GREEN: set( 34, 139, 34); break;
|
||||
case GOLD: set(255, 215, 0); break;
|
||||
case GREEN_YELLOW: set(173, 255, 47); break;
|
||||
case INDIGO: set( 75, 0, 130); break;
|
||||
case OLIVE: set(128, 128, 0); break;
|
||||
case ORANGE: set(255, 165, 0); break;
|
||||
case ORANGE_RED: set(255, 69, 0); break;
|
||||
case ORCHID: set(218, 112, 214); break;
|
||||
case PINK: set(255, 192, 203); break;
|
||||
case PURPLE: set(128, 0, 128); break;
|
||||
case SEA_GREEN: set( 46, 139, 87); break;
|
||||
case SKY_BLUE: set(135, 206, 235); break;
|
||||
case VIOLET: set(238, 130, 238); break;
|
||||
case YELLOW_GREEN: set(154, 205, 50); break;
|
||||
|
||||
default: CVF_FAIL_MSG("Unknown ColorIdent");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color3ub::Color3ub(const Color3f& other)
|
||||
{
|
||||
m_rgb[0] = static_cast<ubyte>(other.r()*255.0f);
|
||||
m_rgb[1] = static_cast<ubyte>(other.g()*255.0f);
|
||||
m_rgb[2] = static_cast<ubyte>(other.b()*255.0f);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Assignment operator
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color3ub& Color3ub::operator=(const Color3ub& rhs)
|
||||
{
|
||||
m_rgb[0] = rhs.m_rgb[0];
|
||||
m_rgb[1] = rhs.m_rgb[1];
|
||||
m_rgb[2] = rhs.m_rgb[2];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Assignment from ColorIdent
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color3ub& Color3ub::operator=(ColorIdent colorIdent)
|
||||
{
|
||||
return operator=(Color3ub(colorIdent));
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool Color3ub::operator==(const Color3ub& rhs) const
|
||||
{
|
||||
if (m_rgb[0] == rhs.m_rgb[0] &&
|
||||
m_rgb[1] == rhs.m_rgb[1] &&
|
||||
m_rgb[2] == rhs.m_rgb[2])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool Color3ub::operator!=(const Color3ub& rhs) const
|
||||
{
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
ubyte Color3ub::r() const
|
||||
{
|
||||
return m_rgb[0];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
ubyte Color3ub::g() const
|
||||
{
|
||||
return m_rgb[1];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
ubyte Color3ub::b() const
|
||||
{
|
||||
return m_rgb[2];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get modifiable reference to the red color component.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
ubyte& Color3ub::r()
|
||||
{
|
||||
return m_rgb[0];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get modifiable reference to the green color component.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
ubyte& Color3ub::g()
|
||||
{
|
||||
return m_rgb[1];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get modifiable reference to the blue color component.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
ubyte& Color3ub::b()
|
||||
{
|
||||
return m_rgb[2];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Sets all color components
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void Color3ub::set(ubyte r, ubyte g, ubyte b)
|
||||
{
|
||||
m_rgb[0] = r;
|
||||
m_rgb[1] = g;
|
||||
m_rgb[2] = b;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const ubyte* Color3ub::ptr() const
|
||||
{
|
||||
return m_rgb;
|
||||
}
|
||||
|
||||
|
||||
} // namespace cvf
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace cvf {
|
||||
|
||||
// Forward declarations
|
||||
class Color3ub;
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Abstract base class for RGB colors
|
||||
//
|
||||
//==================================================================================================
|
||||
class Color3
|
||||
{
|
||||
public:
|
||||
enum ColorIdent
|
||||
{
|
||||
RED, ///< Pure red (255, 0, 0)
|
||||
GREEN, ///< Pure greed (0, 255, 0)
|
||||
BLUE, ///< Pure blue (0, 0, 255)
|
||||
YELLOW, ///< Yellow (255, 255, 0)
|
||||
CYAN, ///< Cyan (0, 255, 255)
|
||||
MAGENTA, ///< Magenta (255, 0, 255)
|
||||
|
||||
WHITE, ///< White
|
||||
BLACK, ///< Black
|
||||
LIGHT_GRAY, ///< Light gray (192, 192, 192)
|
||||
GRAY, ///< Gray (128, 128, 128)
|
||||
DARK_GRAY, ///< Dark gray (64, 64, 64)
|
||||
|
||||
BROWN, ///< Brown (165, 42, 42)
|
||||
CRIMSON, ///< Crimson (220, 20, 60)
|
||||
DARK_BLUE, ///< Dark blue (0, 0, 139)
|
||||
DARK_YELLOW, ///< Dark yellow (139, 139, 0)
|
||||
DARK_CYAN, ///< Dark cyan (0, 139, 139)
|
||||
DARK_GREEN, ///< Dark green (0, 100, 0)
|
||||
DARK_MAGENTA, ///< Dark magenta (139, 0, 139)
|
||||
DARK_ORANGE, ///< Dark orange (255, 140, 0)
|
||||
DARK_RED, ///< Dark red (139, 0, 0)
|
||||
DARK_VIOLET, ///< Dark violet (148, 0, 211)
|
||||
DEEP_PINK, ///< Deep pink (255, 20, 147)
|
||||
FOREST_GREEN, ///< Forest green (34, 139, 34)
|
||||
GOLD, ///< Gold (255, 215, 0)
|
||||
GREEN_YELLOW, ///< Green yellow (173, 255, 47)
|
||||
INDIGO, ///< Indigo (75, 0, 130)
|
||||
OLIVE, ///< Olive (128, 128, 0)
|
||||
ORANGE, ///< Orange (255, 165, 0)
|
||||
ORANGE_RED, ///< Orange red (255, 69, 0)
|
||||
ORCHID, ///< Orchid (218, 112, 214)
|
||||
PINK, ///< Pink (255, 192, 203)
|
||||
PURPLE, ///< Purple (128, 0, 128)
|
||||
SEA_GREEN, ///< Sea green (46, 139, 87)
|
||||
SKY_BLUE, ///< Sky blue (135, 206, 235)
|
||||
VIOLET, ///< Violet (238, 130, 238)
|
||||
YELLOW_GREEN ///< Yellow green (154, 205, 50)
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Floating point RGB colors
|
||||
//
|
||||
//==================================================================================================
|
||||
class Color3f : public Color3
|
||||
{
|
||||
public:
|
||||
Color3f();
|
||||
Color3f(float r, float g, float b);
|
||||
Color3f(const Color3f& other);
|
||||
Color3f(ColorIdent colorIdent);
|
||||
explicit Color3f(const Color3ub& other);
|
||||
|
||||
Color3f& operator=(const Color3f& rhs);
|
||||
Color3f& operator=(ColorIdent colorIdent);
|
||||
bool operator==(const Color3f& rhs) const;
|
||||
bool operator!=(const Color3f& rhs) const;
|
||||
|
||||
float r() const;
|
||||
float g() const;
|
||||
float b() const;
|
||||
float& r();
|
||||
float& g();
|
||||
float& b();
|
||||
void set(float r, float g, float b);
|
||||
|
||||
bool isValid() const;
|
||||
const float* ptr() const;
|
||||
|
||||
ubyte rByte() const;
|
||||
ubyte gByte() const;
|
||||
ubyte bByte() const;
|
||||
|
||||
static Color3f fromByteColor(ubyte r, ubyte g, ubyte b);
|
||||
|
||||
private:
|
||||
float m_rgb[3];
|
||||
};
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Unsigned byte RGB colors
|
||||
//
|
||||
//==================================================================================================
|
||||
class Color3ub : public Color3
|
||||
{
|
||||
public:
|
||||
Color3ub();
|
||||
Color3ub(ubyte r, ubyte g, ubyte b);
|
||||
Color3ub(const Color3ub& other);
|
||||
Color3ub(ColorIdent colorIdent);
|
||||
explicit Color3ub(const Color3f& other);
|
||||
|
||||
Color3ub& operator=(const Color3ub& rhs);
|
||||
Color3ub& operator=(ColorIdent colorIdent);
|
||||
bool operator==(const Color3ub& rhs) const;
|
||||
bool operator!=(const Color3ub& rhs) const;
|
||||
|
||||
ubyte r() const;
|
||||
ubyte g() const;
|
||||
ubyte b() const;
|
||||
ubyte& r();
|
||||
ubyte& g();
|
||||
ubyte& b();
|
||||
void set(ubyte r, ubyte g, ubyte b);
|
||||
|
||||
const ubyte* ptr() const;
|
||||
|
||||
private:
|
||||
ubyte m_rgb[3];
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,541 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfColor4.h"
|
||||
#include "cvfColor3.h"
|
||||
#include "cvfMath.h"
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::Color4f
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// Class for storing and manipulating 4-component RGBA colors
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Default constructor, initializes object to RGB=0.0 and Alpha=1.0
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color4f::Color4f()
|
||||
{
|
||||
m_rgba[0] = 0.0f;
|
||||
m_rgba[1] = 0.0f;
|
||||
m_rgba[2] = 0.0f;
|
||||
m_rgba[3] = 1.0f;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color4f::Color4f(float r, float g, float b, float alpha)
|
||||
{
|
||||
m_rgba[0] = r;
|
||||
m_rgba[1] = g;
|
||||
m_rgba[2] = b;
|
||||
m_rgba[3] = alpha;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color4f::Color4f(const Color4f& other)
|
||||
{
|
||||
m_rgba[0] = other.m_rgba[0];
|
||||
m_rgba[1] = other.m_rgba[1];
|
||||
m_rgba[2] = other.m_rgba[2];
|
||||
m_rgba[3] = other.m_rgba[3];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Construct from 3 component RGB color. Alpha value will be set to 1.0
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color4f::Color4f(const Color3f& rgbColor)
|
||||
{
|
||||
m_rgba[0] = rgbColor.r();
|
||||
m_rgba[1] = rgbColor.g();
|
||||
m_rgba[2] = rgbColor.b();
|
||||
m_rgba[3] = 1.0f;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color4f::Color4f(const Color3f& rgbColor, float alpha)
|
||||
{
|
||||
m_rgba[0] = rgbColor.r();
|
||||
m_rgba[1] = rgbColor.g();
|
||||
m_rgba[2] = rgbColor.b();
|
||||
m_rgba[3] = alpha;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color4f::Color4f(Color3::ColorIdent colorIdent)
|
||||
{
|
||||
Color3f rgb(colorIdent);
|
||||
m_rgba[0] = rgb.r();
|
||||
m_rgba[1] = rgb.g();
|
||||
m_rgba[2] = rgb.b();
|
||||
m_rgba[3] = 1.0f;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color4f::Color4f(const Color4ub& other)
|
||||
{
|
||||
m_rgba[0] = static_cast<float>(other.r())/255.0f;
|
||||
m_rgba[1] = static_cast<float>(other.g())/255.0f;
|
||||
m_rgba[2] = static_cast<float>(other.b())/255.0f;
|
||||
m_rgba[3] = static_cast<float>(other.a())/255.0f;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color4f& Color4f::operator=(const Color4f& rhs)
|
||||
{
|
||||
m_rgba[0] = rhs.m_rgba[0];
|
||||
m_rgba[1] = rhs.m_rgba[1];
|
||||
m_rgba[2] = rhs.m_rgba[2];
|
||||
m_rgba[3] = rhs.m_rgba[3];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool Color4f::operator==(const Color4f& rhs) const
|
||||
{
|
||||
if (m_rgba[0] == rhs.m_rgba[0] &&
|
||||
m_rgba[1] == rhs.m_rgba[1] &&
|
||||
m_rgba[2] == rhs.m_rgba[2] &&
|
||||
m_rgba[3] == rhs.m_rgba[3])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool Color4f::operator!=(const Color4f& rhs) const
|
||||
{
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns the red color component of this color
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const float& Color4f::r() const
|
||||
{
|
||||
return m_rgba[0];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns the green color component of this color
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const float& Color4f::g() const
|
||||
{
|
||||
return m_rgba[1];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns the blue color component of this color
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const float& Color4f::b() const
|
||||
{
|
||||
return m_rgba[2];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns the alpha color component of this color
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const float& Color4f::a() const
|
||||
{
|
||||
return m_rgba[3];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get modifiable reference to the red color component.
|
||||
///
|
||||
/// Used for setting the color, e.g. <tt>r() = 0.5f</tt>
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
float& Color4f::r()
|
||||
{
|
||||
return m_rgba[0];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get modifiable reference to the green color component.
|
||||
///
|
||||
/// Used for setting the color, e.g. <tt>g() = 0.5f</tt>
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
float& Color4f::g()
|
||||
{
|
||||
return m_rgba[1];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get modifiable reference to the blue color component.
|
||||
///
|
||||
/// Used for setting the color, e.g. <tt>b() = 0.5f</tt>
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
float& Color4f::b()
|
||||
{
|
||||
return m_rgba[2];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get modifiable reference to the alpha component.
|
||||
///
|
||||
/// Used for setting the color, e.g. <tt>a() = 0.5f</tt>
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
float& Color4f::a()
|
||||
{
|
||||
return m_rgba[3];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Sets all color components
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void Color4f::set(float r, float g, float b, float alpha)
|
||||
{
|
||||
m_rgba[0] = r;
|
||||
m_rgba[1] = g;
|
||||
m_rgba[2] = b;
|
||||
m_rgba[3] = alpha;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set from 3-component RGB color and separate alpha factor
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void Color4f::set(const Color3f& rgbColor, float alpha)
|
||||
{
|
||||
m_rgba[0] = rgbColor.r();
|
||||
m_rgba[1] = rgbColor.g();
|
||||
m_rgba[2] = rgbColor.b();
|
||||
m_rgba[3] = alpha;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set from 3-component RGB color. Alpha will be set to 1.0
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void Color4f::set(const Color3f& rgbColor)
|
||||
{
|
||||
m_rgba[0] = rgbColor.r();
|
||||
m_rgba[1] = rgbColor.g();
|
||||
m_rgba[2] = rgbColor.b();
|
||||
m_rgba[3] = 1.0f;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Query whether this color is valid
|
||||
///
|
||||
/// For a color to be considered valid, all the component values must be in the range 0.0 to 1.0
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool Color4f::isValid() const
|
||||
{
|
||||
if (!Math::valueInRange(m_rgba[0], 0.0f, 1.0f)) return false;
|
||||
if (!Math::valueInRange(m_rgba[1], 0.0f, 1.0f)) return false;
|
||||
if (!Math::valueInRange(m_rgba[2], 0.0f, 1.0f)) return false;
|
||||
if (!Math::valueInRange(m_rgba[3], 0.0f, 1.0f)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const float* Color4f::ptr() const
|
||||
{
|
||||
return m_rgba;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Convert to 3-component RGB color by dropping the alpha value
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color3f Color4f::toColor3f() const
|
||||
{
|
||||
return Color3f(m_rgba[0], m_rgba[1], m_rgba[2]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::Color4ub
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// Class for storing unsigned byte RGBA colors
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Default constructor, initializes object to RGB=0.0 and Alpha=1.0
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color4ub::Color4ub()
|
||||
{
|
||||
m_rgba[0] = 0;
|
||||
m_rgba[1] = 0;
|
||||
m_rgba[2] = 0;
|
||||
m_rgba[3] = 255;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Constructor with initialization of all components
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color4ub::Color4ub(ubyte r, ubyte g, ubyte b, ubyte a)
|
||||
{
|
||||
m_rgba[0] = r;
|
||||
m_rgba[1] = g;
|
||||
m_rgba[2] = b;
|
||||
m_rgba[3] = a;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Copy constructor
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color4ub::Color4ub(const Color4ub& other)
|
||||
{
|
||||
m_rgba[0] = other.m_rgba[0];
|
||||
m_rgba[1] = other.m_rgba[1];
|
||||
m_rgba[2] = other.m_rgba[2];
|
||||
m_rgba[3] = other.m_rgba[3];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color4ub::Color4ub(const Color3ub& rgbColor, ubyte a)
|
||||
{
|
||||
m_rgba[0] = rgbColor.r();
|
||||
m_rgba[1] = rgbColor.g();
|
||||
m_rgba[2] = rgbColor.b();
|
||||
m_rgba[3] = a;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color4ub::Color4ub(const Color3ub& rgbColor)
|
||||
{
|
||||
m_rgba[0] = rgbColor.r();
|
||||
m_rgba[1] = rgbColor.g();
|
||||
m_rgba[2] = rgbColor.b();
|
||||
m_rgba[3] = 255;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color4ub::Color4ub(Color3::ColorIdent colorIdent)
|
||||
{
|
||||
Color3ub color3(colorIdent);
|
||||
|
||||
set(color3.r(), color3.g(), color3.b(), 255);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color4ub::Color4ub(const Color4f& other)
|
||||
{
|
||||
m_rgba[0] = static_cast<ubyte>(other.r()*255.0f);
|
||||
m_rgba[1] = static_cast<ubyte>(other.g()*255.0f);
|
||||
m_rgba[2] = static_cast<ubyte>(other.b()*255.0f);
|
||||
m_rgba[3] = static_cast<ubyte>(other.a()*255.0f);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Assignment operator
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Color4ub& Color4ub::operator=(const Color4ub& rhs)
|
||||
{
|
||||
m_rgba[0] = rhs.m_rgba[0];
|
||||
m_rgba[1] = rhs.m_rgba[1];
|
||||
m_rgba[2] = rhs.m_rgba[2];
|
||||
m_rgba[3] = rhs.m_rgba[3];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool Color4ub::operator==(const Color4ub& rhs) const
|
||||
{
|
||||
if (m_rgba[0] == rhs.m_rgba[0] &&
|
||||
m_rgba[1] == rhs.m_rgba[1] &&
|
||||
m_rgba[2] == rhs.m_rgba[2] &&
|
||||
m_rgba[3] == rhs.m_rgba[3])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool Color4ub::operator!=(const Color4ub& rhs) const
|
||||
{
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
ubyte Color4ub::r() const
|
||||
{
|
||||
return m_rgba[0];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
ubyte Color4ub::g() const
|
||||
{
|
||||
return m_rgba[1];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
ubyte Color4ub::b() const
|
||||
{
|
||||
return m_rgba[2];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
ubyte Color4ub::a() const
|
||||
{
|
||||
return m_rgba[3];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get modifiable reference to the red color component.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
ubyte& Color4ub::r()
|
||||
{
|
||||
return m_rgba[0];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get modifiable reference to the green color component.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
ubyte& Color4ub::g()
|
||||
{
|
||||
return m_rgba[1];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get modifiable reference to the blue color component.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
ubyte& Color4ub::b()
|
||||
{
|
||||
return m_rgba[2];
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get modifiable reference to the alpha color component.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
ubyte& Color4ub::a()
|
||||
{
|
||||
return m_rgba[3];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Sets all color components
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void Color4ub::set(ubyte r, ubyte g, ubyte b, ubyte a)
|
||||
{
|
||||
m_rgba[0] = r;
|
||||
m_rgba[1] = g;
|
||||
m_rgba[2] = b;
|
||||
m_rgba[3] = a;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const ubyte* Color4ub::ptr() const
|
||||
{
|
||||
return m_rgba;
|
||||
}
|
||||
|
||||
} // namespace cvf
|
||||
@@ -0,0 +1,107 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfColor3.h"
|
||||
|
||||
namespace cvf {
|
||||
|
||||
class Color4ub;
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Class for RGBA colors
|
||||
//
|
||||
//==================================================================================================
|
||||
class Color4f
|
||||
{
|
||||
public:
|
||||
Color4f();
|
||||
Color4f(float r, float g, float b, float alpha);
|
||||
Color4f(const Color4f& other);
|
||||
Color4f(const Color3f& rgbColor, float alpha);
|
||||
explicit Color4f(const Color3f& rgbColor);
|
||||
explicit Color4f(Color3::ColorIdent colorIdent);
|
||||
explicit Color4f(const Color4ub& other);
|
||||
|
||||
Color4f& operator=(const Color4f& rhs);
|
||||
bool operator==(const Color4f& rhs) const;
|
||||
bool operator!=(const Color4f& rhs) const;
|
||||
|
||||
const float& r() const;
|
||||
const float& g() const;
|
||||
const float& b() const;
|
||||
const float& a() const;
|
||||
float& r();
|
||||
float& g();
|
||||
float& b();
|
||||
float& a();
|
||||
|
||||
void set(float r, float g, float b, float alpha);
|
||||
void set(const Color3f& rgbColor, float alpha);
|
||||
void set(const Color3f& rgbColor);
|
||||
|
||||
bool isValid() const;
|
||||
const float* ptr() const;
|
||||
|
||||
Color3f toColor3f() const;
|
||||
|
||||
private:
|
||||
float m_rgba[4];
|
||||
};
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Unsigned byte RGBA colors
|
||||
//
|
||||
//==================================================================================================
|
||||
class Color4ub
|
||||
{
|
||||
public:
|
||||
Color4ub();
|
||||
Color4ub(ubyte r, ubyte g, ubyte b, ubyte a);
|
||||
Color4ub(const Color4ub& other);
|
||||
Color4ub(const Color3ub& rgbColor, ubyte a);
|
||||
explicit Color4ub(const Color3ub& rgbColor);
|
||||
explicit Color4ub(Color3::ColorIdent colorIdent);
|
||||
explicit Color4ub(const Color4f& other);
|
||||
|
||||
Color4ub& operator=(const Color4ub& rhs);
|
||||
bool operator==(const Color4ub& rhs) const;
|
||||
bool operator!=(const Color4ub& rhs) const;
|
||||
|
||||
ubyte r() const;
|
||||
ubyte g() const;
|
||||
ubyte b() const;
|
||||
ubyte a() const;
|
||||
ubyte& r();
|
||||
ubyte& g();
|
||||
ubyte& b();
|
||||
ubyte& a();
|
||||
void set(ubyte r, ubyte g, ubyte b, ubyte a);
|
||||
|
||||
const ubyte* ptr() const;
|
||||
|
||||
private:
|
||||
ubyte m_rgba[4];
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
// Define this one to tell windows.h to not define min() and max() as macros
|
||||
#if defined WIN32 && !defined NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
|
||||
|
||||
// Used to keep track of all instances of classes derived from Object.
|
||||
// Can be used to detect memory leaks in combination with the static member
|
||||
// functions: Object::activeObjectInstances() and Object::dumpActiveObjectInstances()
|
||||
// 0 - disable tracking of active object instances
|
||||
// 1 - track active instances in debug builds
|
||||
// 2 - track active instances in BOTH debug and release builds
|
||||
#ifndef CVF_TRACK_ACTIVE_OBJECT_INSTANCES
|
||||
#define CVF_TRACK_ACTIVE_OBJECT_INSTANCES 0
|
||||
#endif
|
||||
|
||||
|
||||
// Behavior of assert macros
|
||||
// In debug builds, all asserts are in action, including tight asserts
|
||||
// In release builds, tight asserts are disabled by default. Normal asserts are still in action (including CVF_FAIL_...)
|
||||
|
||||
#ifndef CVF_ENABLE_ASSERTS
|
||||
#define CVF_ENABLE_ASSERTS 1
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef CVF_ENABLE_TIGHT_ASSERTS
|
||||
#ifdef _DEBUG
|
||||
#define CVF_ENABLE_TIGHT_ASSERTS 1
|
||||
#else
|
||||
#define CVF_ENABLE_TIGHT_ASSERTS 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,204 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfDebugTimer.h"
|
||||
#include "cvfTimer.h"
|
||||
#include "cvfTrace.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::DebugTimer
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// Debug timer class for reporting timing info via the static Trace class
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Constructor, starts the timer
|
||||
///
|
||||
/// \param prefix This text will be prepended for all trace outputs. Can be NULL
|
||||
/// \param operationMode Either NORMAL (the default) or DISABLED. Specifying DISABLED effectively
|
||||
/// disables all functionality in the class.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
DebugTimer::DebugTimer(const char* prefix, OperationMode operationMode)
|
||||
: m_timer(NULL),
|
||||
m_prefix(NULL),
|
||||
m_messageCount(0)
|
||||
{
|
||||
if (operationMode == NORMAL)
|
||||
{
|
||||
if (prefix)
|
||||
{
|
||||
m_prefix = new String(prefix);
|
||||
}
|
||||
|
||||
m_timer = new Timer();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Destructor
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
DebugTimer::~DebugTimer()
|
||||
{
|
||||
delete m_prefix;
|
||||
delete m_timer;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Restart timer.
|
||||
///
|
||||
/// If msg is specified this method will show this text as trace output. Else nothing is shown.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void DebugTimer::restart(const char* msg)
|
||||
{
|
||||
if (!m_timer) return;
|
||||
|
||||
m_timer->restart();
|
||||
|
||||
if (msg)
|
||||
{
|
||||
String outputText = makeMessageStartString(msg);
|
||||
Trace::show(outputText);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Report elapsed time, in seconds. msg is appended if provided.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void DebugTimer::reportTime(const char* msg)
|
||||
{
|
||||
if (!m_timer) return;
|
||||
|
||||
double time = m_timer->time();
|
||||
|
||||
String outputText = makeMessageStartString(msg) + ": " + String::number(time, 'f', 6) + " sec";
|
||||
Trace::show(outputText);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Report elapsed time, in milliseconds. msg is appended if provided.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void DebugTimer::reportTimeMS(const char* msg )
|
||||
{
|
||||
if (!m_timer) return;
|
||||
|
||||
double timeMS = m_timer->time() * 1000.0;
|
||||
|
||||
String outputText = makeMessageStartString(msg) + ": " + String::number(timeMS, 'f', 3) + " ms";
|
||||
Trace::show(outputText);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Report lap time, in seconds. msg is appended if provided.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void DebugTimer::reportLapTime(const char* msg)
|
||||
{
|
||||
if (!m_timer) return;
|
||||
|
||||
double lapTime = m_timer->lapTime();
|
||||
|
||||
String outputText = makeMessageStartString(msg) + ": " + String::number(lapTime, 'f', 6) + " sec";
|
||||
Trace::show(outputText);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Report lap time, in milliseconds. msg is appended if provided.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void DebugTimer::reportLapTimeMS(const char* msg)
|
||||
{
|
||||
if (!m_timer) return;
|
||||
|
||||
double lapTimeMS = m_timer->lapTime() * 1000.0;
|
||||
|
||||
String outputText = makeMessageStartString(msg) + ": " + String::number(lapTimeMS, 'f', 3) + " ms";
|
||||
Trace::show(outputText);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Show trace output with message count, optional prefix and provided text.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void DebugTimer::echoMessage(const char* format, ...)
|
||||
{
|
||||
if (!m_timer) return;
|
||||
|
||||
// Create the printf-style string and send it to the console and trace file
|
||||
// TODO! Note: var-arg is solved locally here, but needs to be revisited e.g. in String class
|
||||
va_list argList;
|
||||
va_start(argList, format);
|
||||
|
||||
const int maxFormatLength = 4000;
|
||||
char temp[maxFormatLength + 1];
|
||||
|
||||
#ifdef WIN32
|
||||
_vsnprintf_s(temp, maxFormatLength, format, argList);
|
||||
#else
|
||||
vsprintf(temp, format, argList);
|
||||
#endif
|
||||
|
||||
va_end(argList);
|
||||
|
||||
String outputText = makeMessageStartString(temp);
|
||||
|
||||
Trace::show(outputText);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Generate message string with message count, optional prefix and optional msg text.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
String DebugTimer::makeMessageStartString(const char* msg)
|
||||
{
|
||||
String outputText = String(m_messageCount);
|
||||
m_messageCount++;
|
||||
|
||||
if (m_prefix)
|
||||
{
|
||||
outputText += String(": ");
|
||||
outputText += *m_prefix;
|
||||
}
|
||||
|
||||
if (msg)
|
||||
{
|
||||
outputText += ": ";
|
||||
outputText += msg;
|
||||
}
|
||||
|
||||
return outputText;
|
||||
}
|
||||
|
||||
|
||||
} // namespace cvf
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfString.h"
|
||||
|
||||
|
||||
namespace cvf {
|
||||
|
||||
class Timer;
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
//
|
||||
// Timer class
|
||||
//
|
||||
//=================================================================================================
|
||||
class DebugTimer
|
||||
{
|
||||
public:
|
||||
enum OperationMode
|
||||
{
|
||||
NORMAL, ///< Normal operation
|
||||
DISABLED ///< Disables all functionality in the class
|
||||
};
|
||||
|
||||
public:
|
||||
DebugTimer(const char* prefix, OperationMode operationMode = NORMAL);
|
||||
~DebugTimer();
|
||||
|
||||
void restart(const char* msg = NULL);
|
||||
|
||||
void reportTime(const char* msg = NULL);
|
||||
void reportTimeMS(const char* msg = NULL);
|
||||
void reportLapTime(const char* msg = NULL);
|
||||
void reportLapTimeMS(const char* msg = NULL);
|
||||
|
||||
void echoMessage(const char* format, ...);
|
||||
|
||||
private:
|
||||
String makeMessageStartString(const char* msg);
|
||||
|
||||
private:
|
||||
Timer* m_timer; ///< The actual timer object to use
|
||||
String* m_prefix; ///< String to prefix all output
|
||||
int m_messageCount; ///< Counts number of messages returned
|
||||
|
||||
CVF_DISABLE_COPY_AND_ASSIGN(DebugTimer);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
//
|
||||
// Flags class
|
||||
//
|
||||
//=================================================================================================
|
||||
template<typename FlagEnum>
|
||||
class Flags
|
||||
{
|
||||
public:
|
||||
inline Flags();
|
||||
inline Flags(const Flags& other);
|
||||
inline Flags(FlagEnum flag);
|
||||
|
||||
inline Flags& operator=(const Flags& rhs);
|
||||
inline Flags& operator=(FlagEnum flag);
|
||||
|
||||
inline Flags& operator|=(const Flags& rhs);
|
||||
inline Flags operator|(const Flags& rhs) const;
|
||||
inline Flags& operator&=(const Flags& rhs);
|
||||
inline Flags operator&(const Flags& rhs) const;
|
||||
|
||||
inline bool operator==(const Flags& rhs) const;
|
||||
inline bool operator==(int rhs) const;
|
||||
inline bool operator!=(const Flags& rhs) const;
|
||||
inline bool operator!=(int rhs) const;
|
||||
inline bool testFlag(FlagEnum flag) const;
|
||||
|
||||
private:
|
||||
int m_bitfield;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#include "cvfFlags.inl"
|
||||
@@ -0,0 +1,179 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::Flags
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// The Flags class provides a type-safe way of storing OR-combinations of enum values
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Default constructor
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename FlagEnum>
|
||||
inline Flags<FlagEnum>::Flags()
|
||||
: m_bitfield(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Copy constructor
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename FlagEnum>
|
||||
inline Flags<FlagEnum>::Flags(const Flags& other)
|
||||
: m_bitfield(other.m_bitfield)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Constructor with initialization
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename FlagEnum>
|
||||
inline Flags<FlagEnum>::Flags(FlagEnum flag)
|
||||
: m_bitfield(flag)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Assignment operator
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename FlagEnum>
|
||||
inline Flags<FlagEnum>& Flags<FlagEnum>::operator=(const Flags& rhs)
|
||||
{
|
||||
m_bitfield = rhs.m_bitfield;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Assignment operator
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename FlagEnum>
|
||||
inline Flags<FlagEnum>& Flags<FlagEnum>::operator=(FlagEnum flag)
|
||||
{
|
||||
m_bitfield = flag;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Performs a bitwise OR operation with rhs and stores the result in this Flags object.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename FlagEnum>
|
||||
inline Flags<FlagEnum>& Flags<FlagEnum>::operator|=(const Flags& rhs)
|
||||
{
|
||||
m_bitfield |= rhs.m_bitfield;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Performs a bitwise OR operation with rhs and returns new object
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename FlagEnum>
|
||||
inline Flags<FlagEnum> Flags<FlagEnum>::operator|(const Flags& rhs) const
|
||||
{
|
||||
Flags ret(*this);
|
||||
return (ret |= rhs);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Performs a bitwise AND operation with rhs and stores the result in this Flags object.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename FlagEnum>
|
||||
inline Flags<FlagEnum>& Flags<FlagEnum>::operator&=(const Flags& rhs)
|
||||
{
|
||||
m_bitfield &= rhs.m_bitfield;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Performs a bitwise AND operation with rhs and returns new object
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename FlagEnum>
|
||||
inline Flags<FlagEnum> Flags<FlagEnum>::operator&(const Flags& rhs) const
|
||||
{
|
||||
Flags ret(*this);
|
||||
return (ret &= rhs);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Comparison operator, equality
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename FlagEnum>
|
||||
inline bool Flags<FlagEnum>::operator==(const Flags& rhs) const
|
||||
{
|
||||
return m_bitfield == rhs.m_bitfield;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Comparison operator, equality
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename FlagEnum>
|
||||
inline bool Flags<FlagEnum>::operator==(int rhs) const
|
||||
{
|
||||
return m_bitfield == rhs;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Comparison operator, not equal
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename FlagEnum>
|
||||
inline bool Flags<FlagEnum>::operator!=(const Flags& rhs) const
|
||||
{
|
||||
return m_bitfield != rhs.m_bitfield;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Comparison operator, not equal
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename FlagEnum>
|
||||
inline bool Flags<FlagEnum>::operator!=(int rhs) const
|
||||
{
|
||||
return m_bitfield != rhs;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Return true only if ALL bits in flag are set
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename FlagEnum>
|
||||
inline bool Flags<FlagEnum>::testFlag(FlagEnum flag) const
|
||||
{
|
||||
return ((m_bitfield & flag) == flag);
|
||||
}
|
||||
|
||||
|
||||
} // namespace cvf
|
||||
@@ -0,0 +1,53 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::FunctorRange
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// Implements an iteration range for use with our functors.
|
||||
/// The class is designed to be compatible with TBB's blocked_range class with regards to
|
||||
/// the functor's requirements
|
||||
///
|
||||
//==================================================================================================
|
||||
template <typename T>
|
||||
class FunctorRange
|
||||
{
|
||||
public:
|
||||
FunctorRange(T beginIndex, T endIndex)
|
||||
: m_beginIndex(beginIndex), m_endIndex(endIndex) {}
|
||||
|
||||
inline T begin() const { return m_beginIndex; } ///< The first index included in the range
|
||||
inline T end() const { return m_endIndex; } ///< Index one past last the last index to be included in the range
|
||||
|
||||
private:
|
||||
T m_beginIndex; // The first index to be included in the iteration.
|
||||
T m_endIndex; // The index one past the last index to be included in the iteration
|
||||
};
|
||||
|
||||
|
||||
} // cvf
|
||||
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
// Doxygen module definition
|
||||
/// \ingroup CeeVizFramework
|
||||
/// @{
|
||||
/// \defgroup Core Core module
|
||||
/// @}
|
||||
|
||||
/// \defgroup CeeVizFramework CeeViz Framework Basis
|
||||
|
||||
// Intentionally on top to be included first
|
||||
#include "cvfBase.h"
|
||||
|
||||
#include "cvfArray.h"
|
||||
#include "cvfAssert.h"
|
||||
#include "cvfBase64.h"
|
||||
#include "cvfCharArray.h"
|
||||
#include "cvfCollection.h"
|
||||
#include "cvfColor3.h"
|
||||
#include "cvfColor4.h"
|
||||
#include "cvfDebugTimer.h"
|
||||
#include "cvfFlags.h"
|
||||
#include "cvfFunctorRange.h"
|
||||
#include "cvfLogger.h"
|
||||
#include "cvfMath.h"
|
||||
#include "cvfMatrix4.h"
|
||||
#include "cvfObject.h"
|
||||
#include "cvfPlane.h"
|
||||
#include "cvfRect.h"
|
||||
#include "cvfQuat.h"
|
||||
#include "cvfString.h"
|
||||
#include "cvfSystem.h"
|
||||
#include "cvfTBBControl.h"
|
||||
#include "cvfTimer.h"
|
||||
#include "cvfTrace.h"
|
||||
#include "cvfVector2.h"
|
||||
#include "cvfVector3.h"
|
||||
#include "cvfVector4.h"
|
||||
#include "cvfVersion.h"
|
||||
@@ -0,0 +1,112 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfLogger.h"
|
||||
#include "cvfTrace.h"
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::Logger
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// Logger class
|
||||
///
|
||||
/// Currently, output is written using Trace, and special formatting of the string makes it possible
|
||||
/// to navigate to source code using F4 in Visual Studio. See http://msdn.microsoft.com/en-us/library/yxkt8b26.aspx
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Constructor
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Logger::Logger()
|
||||
: m_debugLogging(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Destructor
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Logger::~Logger()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Use file and line to create a specially formatted string for Visual Studio.
|
||||
///
|
||||
/// \param message The actual error message
|
||||
/// \param fileName Use system macro __FILE__ for source code file name
|
||||
/// \param line Use system macro __LINE__ for source code line number
|
||||
///
|
||||
/// __FILE__ and __LINE__ are used to create the variables used to navigate to the line in the
|
||||
/// source code file the error message was logged at.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void Logger::error(const String& message, const char* fileName, int lineNumber)
|
||||
{
|
||||
String tmp;
|
||||
tmp = String(fileName) + "(" + String(lineNumber) + "): error: " + message;
|
||||
|
||||
Trace::show(tmp);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void Logger::enableDebug(bool enableDebugLogging)
|
||||
{
|
||||
m_debugLogging = enableDebugLogging;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool Logger::isDebugEnabled() const
|
||||
{
|
||||
return m_debugLogging;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void Logger::debug(const String& message, const char* /*fileName*/, int /*lineNumber*/)
|
||||
{
|
||||
if (m_debugLogging)
|
||||
{
|
||||
// For now, don't report file and line
|
||||
String tmp;
|
||||
tmp = "debug: " + message;
|
||||
|
||||
Trace::show(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace cvf
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfObject.h"
|
||||
#include "cvfString.h"
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Logger class
|
||||
//
|
||||
//==================================================================================================
|
||||
class Logger : public Object
|
||||
{
|
||||
public:
|
||||
Logger();
|
||||
~Logger();
|
||||
|
||||
void error(const String& message, const char* fileName, int lineNumber);
|
||||
|
||||
void enableDebug(bool enableDebugLogging);
|
||||
bool isDebugEnabled() const;
|
||||
void debug(const String& message, const char* fileName, int lineNumber);
|
||||
|
||||
private:
|
||||
bool m_debugLogging; // Whether debug messages get logged or not
|
||||
};
|
||||
|
||||
|
||||
} // cvf
|
||||
|
||||
|
||||
@@ -0,0 +1,334 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfMath.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::Math
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// Static class providing basic math operations
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
float Math::toRadians(float degrees)
|
||||
{
|
||||
return degrees*PI_F/180.0f;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double Math::toRadians(double degrees)
|
||||
{
|
||||
return degrees*PI_D/180.0;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
float Math::toDegrees(float radians)
|
||||
{
|
||||
return radians*180.0f/PI_F;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double Math::toDegrees(double radians)
|
||||
{
|
||||
return radians*180.0/PI_D;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double Math::cos(double val)
|
||||
{
|
||||
return ::cos(val);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
float Math::cos(float val)
|
||||
{
|
||||
return ::cosf(val);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double Math::acos(double val)
|
||||
{
|
||||
return ::acos(val);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
float Math::acos(float val)
|
||||
{
|
||||
return ::acosf(val);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double Math::sin(double val)
|
||||
{
|
||||
return ::sin(val);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
float Math::sin(float val)
|
||||
{
|
||||
return ::sinf(val);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double Math::asin(double val)
|
||||
{
|
||||
return ::asin(val);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
float Math::asin(float val)
|
||||
{
|
||||
return ::asinf(val);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double Math::tan(double val)
|
||||
{
|
||||
return ::tan(val);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
float Math::tan(float val)
|
||||
{
|
||||
return ::tanf(val);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double Math::atan(double val)
|
||||
{
|
||||
return ::atan(val);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
float Math::atan(float val)
|
||||
{
|
||||
return ::atanf(val);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double Math::sqrt(double val)
|
||||
{
|
||||
return ::sqrt(val);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
float Math::sqrt(float val)
|
||||
{
|
||||
return ::sqrtf(val);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double Math::floor(double val)
|
||||
{
|
||||
return ::floor(val);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
float Math::floor(float val)
|
||||
{
|
||||
return ::floorf(val);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double Math::ceil(double val)
|
||||
{
|
||||
return ::ceil(val);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
float Math::ceil(float val)
|
||||
{
|
||||
return ::ceilf(val);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns the floating-point remainder of x / y
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double Math::fmod(double x, double y)
|
||||
{
|
||||
return ::fmod(x, y);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns the floating-point remainder of x / y
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
float Math::fmod(float x, float y)
|
||||
{
|
||||
return ::fmodf(x, y);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns true if the number is a power of 2
|
||||
///
|
||||
/// The number 0 is not considered a power of 2.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool Math::isPow2(uint number)
|
||||
{
|
||||
// From Bit Twiddling Hacks
|
||||
// http://graphics.stanford.edu/~seander/bithacks.html
|
||||
|
||||
return (number && !(number & (number - 1)));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Round up to the next highest power of 2
|
||||
///
|
||||
/// If the number is already a power of 2 this function will return the same value
|
||||
/// If number if out of range (greater than 2147483648) we cannot represent the next power of 2 and 0 is returned
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
uint Math::roundUpPow2(uint number)
|
||||
{
|
||||
// From Bit Twiddling Hacks
|
||||
// http://graphics.stanford.edu/~seander/bithacks.html
|
||||
|
||||
if (number == 0)
|
||||
{
|
||||
// Handle edge case where number is 0, algo returns 0, which isn't a power of 2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (number > 2147483648u)
|
||||
{
|
||||
// Input is too large, we cannot represent the next power of two
|
||||
return 0;
|
||||
}
|
||||
|
||||
number--;
|
||||
number |= number >> 1;
|
||||
number |= number >> 2;
|
||||
number |= number >> 4;
|
||||
number |= number >> 8;
|
||||
number |= number >> 16;
|
||||
number++;
|
||||
|
||||
return number;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool Math::isUndefined(double val)
|
||||
{
|
||||
if (val < UNDEFINED_DOUBLE_THRESHOLD)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool Math::isUndefined(float val)
|
||||
{
|
||||
if (val < UNDEFINED_FLOAT_THRESHOLD)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace cvf
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Static class providing basic math operations
|
||||
//
|
||||
//==================================================================================================
|
||||
class Math
|
||||
{
|
||||
public:
|
||||
static float toRadians(float degrees);
|
||||
static double toRadians(double degrees);
|
||||
static float toDegrees(float radians);
|
||||
static double toDegrees(double radians);
|
||||
|
||||
static double cos(double val);
|
||||
static float cos(float val);
|
||||
static double acos(double val);
|
||||
static float acos(float val);
|
||||
static double sin(double val);
|
||||
static float sin(float val);
|
||||
static double asin(double val);
|
||||
static float asin(float val);
|
||||
static double tan(double val);
|
||||
static float tan(float val);
|
||||
static double atan(double val);
|
||||
static float atan(float val);
|
||||
|
||||
static double sqrt(double val);
|
||||
static float sqrt(float val);
|
||||
|
||||
static double floor(double val);
|
||||
static float floor(float val);
|
||||
static double ceil(double val);
|
||||
static float ceil(float val);
|
||||
static double fmod(double x, double y);
|
||||
static float fmod(float x, float y);
|
||||
static bool isPow2(uint number);
|
||||
static uint roundUpPow2(uint number);
|
||||
|
||||
static bool isUndefined(double val);
|
||||
static bool isUndefined(float val);
|
||||
|
||||
template<typename T> static bool valueInRange(T val, T min, T max);
|
||||
template<typename T> static T clamp(T val, T minVal, T maxVal);
|
||||
|
||||
template<typename T> static inline T abs(const T& val);
|
||||
template<typename T> static int sign(const T& val);
|
||||
};
|
||||
|
||||
|
||||
const float PI_F = 3.14159265f;
|
||||
const double PI_D = 3.14159265358979323846;
|
||||
const float ONE_THIRD_F = 1.0f/3.0f;
|
||||
const double ONE_THIRD_D = 1.0/3.0;
|
||||
const double SQRT2_F = 1.41421356f; // sqrt(2)
|
||||
const double SQRT2_D = 1.41421356237309504880; // sqrt(2)
|
||||
const double SQRT1_2_F = 0.70710678f; // 1/sqrt(2)
|
||||
const double SQRT1_2_D = 0.70710678118654752440; // 1/sqrt(2)
|
||||
|
||||
const int UNDEFINED_INT = 2147483647;
|
||||
const uint UNDEFINED_UINT = static_cast<uint>(-1); // 4294967295u
|
||||
const size_t UNDEFINED_SIZE_T = static_cast<size_t>(-1);// 18446744073709551615u
|
||||
const double UNDEFINED_DOUBLE = 1.7976931348623158e+308;
|
||||
const double UNDEFINED_DOUBLE_THRESHOLD = 1.00e+308;
|
||||
const float UNDEFINED_FLOAT = 3.402823466e+38f;
|
||||
const float UNDEFINED_FLOAT_THRESHOLD = 2.99e+38f;
|
||||
|
||||
|
||||
|
||||
} // namespace cvf
|
||||
|
||||
#include "cvfMath.inl"
|
||||
@@ -0,0 +1,89 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Check if a value is within the specified range, inclusive.
|
||||
///
|
||||
/// \return Returns true if \a val >= \a min and \a val <= \a max.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
bool Math::valueInRange(T val, T minVal, T maxVal)
|
||||
{
|
||||
CVF_ASSERT(minVal <= maxVal);
|
||||
|
||||
if (val >= minVal && val <= maxVal)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Clamp a value within an inclusive range.
|
||||
///
|
||||
/// \return The clamped value
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
T Math::clamp(T val, T minVal, T maxVal)
|
||||
{
|
||||
CVF_ASSERT(minVal <= maxVal);
|
||||
|
||||
if (val >= minVal && val <= maxVal)
|
||||
{
|
||||
return val;
|
||||
}
|
||||
else if (val > maxVal)
|
||||
{
|
||||
return maxVal;
|
||||
}
|
||||
else
|
||||
{
|
||||
return minVal;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns the absolute value of val
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
T Math::abs(const T& val)
|
||||
{
|
||||
return val >= 0 ? val : -val;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns the sign of val
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
int Math::sign(const T& val)
|
||||
{
|
||||
return val < 0 ? -1 : 1;
|
||||
}
|
||||
|
||||
|
||||
} // namespace cvf
|
||||
@@ -0,0 +1,88 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfSystem.h"
|
||||
#include "cvfVector3.h"
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Template matrix class for 3x3 matrices
|
||||
//
|
||||
//==================================================================================================
|
||||
template<typename S>
|
||||
class Matrix3
|
||||
{
|
||||
public:
|
||||
Matrix3();
|
||||
Matrix3(const Matrix3& other);
|
||||
Matrix3(S m00, S m01, S m02, S m10, S m11, S m12, S m20, S m21, S m22);
|
||||
|
||||
template<typename T>
|
||||
explicit Matrix3(const T& other);
|
||||
|
||||
inline Matrix3& operator=(const Matrix3& rhs);
|
||||
bool operator==(const Matrix3& rhs) const;
|
||||
bool operator!=(const Matrix3& rhs) const;
|
||||
|
||||
const Matrix3 operator*(const Matrix3& rhs) const;
|
||||
|
||||
void setIdentity();
|
||||
bool isIdentity() const;
|
||||
void setZero();
|
||||
bool isZero() const;
|
||||
|
||||
inline S& operator()(int row, int col);
|
||||
inline S operator()(int row, int col) const;
|
||||
inline void setRowCol(int row, int col, S value);
|
||||
inline S rowCol(int row, int col) const;
|
||||
|
||||
bool invert();
|
||||
const Matrix3 getInverted(bool* pInvertible = NULL) const;
|
||||
S determinant() const;
|
||||
void transpose();
|
||||
|
||||
inline const S* ptr() const;
|
||||
|
||||
static Matrix3 fromRotation(Vector3<S> axis, S angle);
|
||||
|
||||
public:
|
||||
static const Matrix3 IDENTITY; ///< Identity matrix
|
||||
static const Matrix3 ZERO; ///< Matrix with all zeros
|
||||
|
||||
private:
|
||||
// Constants for accessing our internal array using standard matrix notation
|
||||
static const int e00 = 0; static const int e01 = 3; static const int e02 = 6;
|
||||
static const int e10 = 1; static const int e11 = 4; static const int e12 = 7;
|
||||
static const int e20 = 2; static const int e21 = 5; static const int e22 = 8;
|
||||
|
||||
private:
|
||||
S m_v[9];
|
||||
};
|
||||
|
||||
typedef Matrix3<float> Mat3f;
|
||||
typedef Matrix3<double> Mat3d;
|
||||
|
||||
}
|
||||
|
||||
#include "cvfMatrix3.inl"
|
||||
@@ -0,0 +1,449 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::Matrix3
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// Matrices are stored internally as a one dimensional array for performance reasons.
|
||||
///
|
||||
/// The internal indices into the 1D array are as follows:
|
||||
///
|
||||
/// <PRE>
|
||||
/// | m00 m01 m02 | | 0 3 6 |
|
||||
/// | m10 m11 m12 | | 1 4 7 |
|
||||
/// | m20 m21 m22 | | 2 5 18 |
|
||||
/// </PRE>
|
||||
///
|
||||
/// See description of Matrix4 for more details on storage
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
template<typename S> Matrix3<S> const Matrix3<S>::IDENTITY;
|
||||
template<typename S> Matrix3<S> const Matrix3<S>::ZERO(0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/// Default constructor. Initializes matrix to identity
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
Matrix3<S>::Matrix3()
|
||||
{
|
||||
setIdentity();
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/// Copy constructor
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
inline Matrix3<S>::Matrix3(const Matrix3& other)
|
||||
{
|
||||
System::memcpy(m_v, sizeof(m_v), other.m_v, sizeof(other.m_v));
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/// Constructor with explicit initialization of all matrix elements.
|
||||
///
|
||||
/// The value of the parameter \a mrc will be placed in row r and column c of the matrix, eg m12
|
||||
/// goes into row 1, column 2.
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
Matrix3<S>::Matrix3(S m00, S m01, S m02, S m10, S m11, S m12, S m20, S m21, S m22)
|
||||
{
|
||||
m_v[e00] = m00;
|
||||
m_v[e10] = m10;
|
||||
m_v[e20] = m20;
|
||||
m_v[e01] = m01;
|
||||
m_v[e11] = m11;
|
||||
m_v[e21] = m21;
|
||||
m_v[e02] = m02;
|
||||
m_v[e12] = m12;
|
||||
m_v[e22] = m22;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
template<typename T>
|
||||
Matrix3<S>::Matrix3(const T& other)
|
||||
{
|
||||
m_v[e00] = static_cast<S>(other.rowCol(0, 0));
|
||||
m_v[e01] = static_cast<S>(other.rowCol(0, 1));
|
||||
m_v[e02] = static_cast<S>(other.rowCol(0, 2));
|
||||
m_v[e10] = static_cast<S>(other.rowCol(1, 0));
|
||||
m_v[e11] = static_cast<S>(other.rowCol(1, 1));
|
||||
m_v[e12] = static_cast<S>(other.rowCol(1, 2));
|
||||
m_v[e20] = static_cast<S>(other.rowCol(2, 0));
|
||||
m_v[e21] = static_cast<S>(other.rowCol(2, 1));
|
||||
m_v[e22] = static_cast<S>(other.rowCol(2, 2));
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/// Assignment operator
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
inline Matrix3<S>& Matrix3<S>::operator=(const Matrix3& obj)
|
||||
{
|
||||
System::memcpy(m_v, sizeof(m_v), obj.m_v, sizeof(obj.m_v));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/// Comparison operator. Checks for equality using exact comparisons.
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
bool Matrix3<S>::operator==(const Matrix3& rhs) const
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 9; i++)
|
||||
{
|
||||
if (m_v[i] != rhs.m_v[i]) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/// Comparison operator. Checks for not equal using exact comparisons.
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
bool Matrix3<S>::operator!=(const Matrix3& rhs) const
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 9; i++)
|
||||
{
|
||||
if (m_v[i] != rhs.m_v[i]) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
const Matrix3<S> Matrix3<S>::operator*(const Matrix3& rhs) const
|
||||
{
|
||||
Matrix3 m;
|
||||
|
||||
int r;
|
||||
for (r = 0; r < 3; r++)
|
||||
{
|
||||
int c;
|
||||
for (c = 0; c < 3; c++)
|
||||
{
|
||||
S val = 0;
|
||||
|
||||
int a;
|
||||
for (a = 0; a < 3; a++)
|
||||
{
|
||||
val += rowCol(r, a)*rhs.rowCol(a, c);
|
||||
}
|
||||
|
||||
m.setRowCol(r, c, val);
|
||||
}
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/// Sets this matrix to identity
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
void Matrix3<S>::setIdentity()
|
||||
{
|
||||
m_v[0] = 1;
|
||||
m_v[1] = 0;
|
||||
m_v[2] = 0;
|
||||
|
||||
m_v[3] = 0;
|
||||
m_v[4] = 1;
|
||||
m_v[5] = 0;
|
||||
|
||||
m_v[6] = 0;
|
||||
m_v[7] = 0;
|
||||
m_v[8] = 1;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/// Check if this matrix is identity using exact comparisons
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
bool Matrix3<S>::isIdentity() const
|
||||
{
|
||||
if (m_v[0] != 1) return false;
|
||||
if (m_v[1] != 0) return false;
|
||||
if (m_v[2] != 0) return false;
|
||||
|
||||
if (m_v[3] != 0) return false;
|
||||
if (m_v[4] != 1) return false;
|
||||
if (m_v[5] != 0) return false;
|
||||
|
||||
if (m_v[6] != 0) return false;
|
||||
if (m_v[7] != 0) return false;
|
||||
if (m_v[8] != 1) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/// Set all matrix elements to 0
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
void Matrix3<S>::setZero()
|
||||
{
|
||||
m_v[0] = 0;
|
||||
m_v[1] = 0;
|
||||
m_v[2] = 0;
|
||||
m_v[3] = 0;
|
||||
m_v[4] = 0;
|
||||
m_v[5] = 0;
|
||||
m_v[6] = 0;
|
||||
m_v[7] = 0;
|
||||
m_v[8] = 0;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/// Returns true if all elements of the matrix are 0. Uses exact comparison.
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
bool Matrix3<S>::isZero() const
|
||||
{
|
||||
if (m_v[0] != 0) return false;
|
||||
if (m_v[1] != 0) return false;
|
||||
if (m_v[2] != 0) return false;
|
||||
|
||||
if (m_v[3] != 0) return false;
|
||||
if (m_v[4] != 0) return false;
|
||||
if (m_v[5] != 0) return false;
|
||||
|
||||
if (m_v[6] != 0) return false;
|
||||
if (m_v[7] != 0) return false;
|
||||
if (m_v[8] != 0) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/// Set the matrix element at the specified row and column
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
inline void Matrix3<S>::setRowCol(int row, int col, S value)
|
||||
{
|
||||
CVF_TIGHT_ASSERT(row >= 0 && row < 3);
|
||||
CVF_TIGHT_ASSERT(col >= 0 && col < 3);
|
||||
|
||||
m_v[3*col + row] = value;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/// Get the matrix element at the specified row and column
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
inline S Matrix3<S>::rowCol(int row, int col) const
|
||||
{
|
||||
CVF_TIGHT_ASSERT(row >= 0 && row < 3);
|
||||
CVF_TIGHT_ASSERT(col >= 0 && col < 3);
|
||||
|
||||
return m_v[3*col + row];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get modifiable reference to the the matrix element at the specified row and column
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
inline S& Matrix3<S>::operator()(int row, int col)
|
||||
{
|
||||
CVF_TIGHT_ASSERT(row >= 0 && row < 3);
|
||||
CVF_TIGHT_ASSERT(col >= 0 && col < 3);
|
||||
|
||||
return m_v[3*col + row];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the matrix element at the specified row and column
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
inline S Matrix3<S>::operator()(int row, int col) const
|
||||
{
|
||||
CVF_TIGHT_ASSERT(row >= 0 && row < 3);
|
||||
CVF_TIGHT_ASSERT(col >= 0 && col < 3);
|
||||
|
||||
return m_v[3*col + row];
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
bool Matrix3<S>::invert()
|
||||
{
|
||||
// Use double internally here
|
||||
double m00 = static_cast<double>(m_v[e00]);
|
||||
double m10 = static_cast<double>(m_v[e10]);
|
||||
double m20 = static_cast<double>(m_v[e20]);
|
||||
double m01 = static_cast<double>(m_v[e01]);
|
||||
double m11 = static_cast<double>(m_v[e11]);
|
||||
double m21 = static_cast<double>(m_v[e21]);
|
||||
double m02 = static_cast<double>(m_v[e02]);
|
||||
double m12 = static_cast<double>(m_v[e12]);
|
||||
double m22 = static_cast<double>(m_v[e22]);
|
||||
|
||||
double det = m00*m11*m22 + m01*m12*m20 + m02*m10*m21 - m00*m12*m21 - m01*m10*m22 - m02*m11*m20;
|
||||
|
||||
if (Math::abs(det) > std::numeric_limits<double>::epsilon())
|
||||
{
|
||||
double invDet = 1/det;
|
||||
|
||||
m_v[e00] = static_cast<S>( (m11*m22 - m12*m21) * invDet );
|
||||
m_v[e01] = static_cast<S>( (m02*m21 - m01*m22) * invDet );
|
||||
m_v[e02] = static_cast<S>( (m01*m12 - m02*m11) * invDet );
|
||||
m_v[e10] = static_cast<S>( (m12*m20 - m10*m22) * invDet );
|
||||
m_v[e11] = static_cast<S>( (m00*m22 - m02*m20) * invDet );
|
||||
m_v[e12] = static_cast<S>( (m02*m10 - m00*m12) * invDet );
|
||||
m_v[e20] = static_cast<S>( (m10*m21 - m11*m20) * invDet );
|
||||
m_v[e21] = static_cast<S>( (m01*m20 - m00*m21) * invDet );
|
||||
m_v[e22] = static_cast<S>( (m00*m11 - m01*m10) * invDet );
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
const Matrix3<S> Matrix3<S>::getInverted(bool* pInvertible) const
|
||||
{
|
||||
Matrix3 m(*this);
|
||||
if (m.invert())
|
||||
{
|
||||
if (pInvertible) *pInvertible = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pInvertible) *pInvertible = false;
|
||||
m.setZero();
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
S Matrix3<S>::determinant() const
|
||||
{
|
||||
S det = m_v[e00]*m_v[e11]*m_v[e22] +
|
||||
m_v[e01]*m_v[e12]*m_v[e20] +
|
||||
m_v[e02]*m_v[e10]*m_v[e21] -
|
||||
m_v[e00]*m_v[e12]*m_v[e21] -
|
||||
m_v[e01]*m_v[e10]*m_v[e22] -
|
||||
m_v[e02]*m_v[e11]*m_v[e20];
|
||||
|
||||
return det;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
void Matrix3<S>::transpose()
|
||||
{
|
||||
S tmp;
|
||||
int i, j;
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
for (j = i + 1; j < 3; j++)
|
||||
{
|
||||
tmp = m_v[j + 3*i];
|
||||
m_v[j + 3*i] = m_v[3*j + i];
|
||||
m_v[3*j + i] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
const S* Matrix3<S>::ptr() const
|
||||
{
|
||||
return m_v;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
Matrix3<S> Matrix3<S>::fromRotation(Vector3<S> axis, S angle)
|
||||
{
|
||||
axis.normalize();
|
||||
|
||||
S rcos = Math::cos(angle);
|
||||
S rsin = Math::sin(angle);
|
||||
|
||||
Matrix3 m;
|
||||
m.m_v[e00] = rcos + axis.x()*axis.x()*(1 - rcos);
|
||||
m.m_v[e10] = axis.z() * rsin + axis.y()*axis.x()*(1 - rcos);
|
||||
m.m_v[e20] = -axis.y() * rsin + axis.z()*axis.x()*(1 - rcos);
|
||||
m.m_v[e01] = -axis.z() * rsin + axis.x()*axis.y()*(1 - rcos);
|
||||
m.m_v[e11] = rcos + axis.y()*axis.y()*(1 - rcos);
|
||||
m.m_v[e21] = axis.x() * rsin + axis.z()*axis.y()*(1 - rcos);
|
||||
m.m_v[e02] = axis.y() * rsin + axis.x()*axis.z()*(1 - rcos);
|
||||
m.m_v[e12] = -axis.x() * rsin + axis.y()*axis.z()*(1 - rcos);
|
||||
m.m_v[e22] = rcos + axis.z()*axis.z()*(1 - rcos);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfSystem.h"
|
||||
#include "cvfVector3.h"
|
||||
#include "cvfVector4.h"
|
||||
#include "cvfMatrix3.h"
|
||||
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Template matrix class for 4x4 matrices
|
||||
//
|
||||
//==================================================================================================
|
||||
template<typename S>
|
||||
class Matrix4
|
||||
{
|
||||
public:
|
||||
Matrix4();
|
||||
Matrix4(const Matrix4& other);
|
||||
Matrix4(S m00, S m01, S m02, S m03, S m10, S m11, S m12, S m13, S m20, S m21, S m22, S m23, S m30, S m31, S m32, S m33);
|
||||
|
||||
explicit Matrix4(const Matrix3<S>& other);
|
||||
|
||||
template<typename T>
|
||||
explicit Matrix4(const T& other);
|
||||
|
||||
inline Matrix4& operator=(const Matrix4& rhs);
|
||||
bool operator==(const Matrix4& rhs) const;
|
||||
bool operator!=(const Matrix4& rhs) const;
|
||||
|
||||
const Matrix4 operator*(const Matrix4& rhs) const;
|
||||
const Vector4<S> operator*(const Vector4<S>& rhs) const;
|
||||
|
||||
void setIdentity();
|
||||
bool isIdentity() const;
|
||||
void setZero();
|
||||
bool isZero() const;
|
||||
|
||||
inline S& operator()(int row, int col);
|
||||
inline S operator()(int row, int col) const;
|
||||
inline void setRowCol(int row, int col, S value);
|
||||
inline S rowCol(int row, int col) const;
|
||||
|
||||
void setRow(int row, const Vector4<S>& vector);
|
||||
Vector4<S> row(int row) const;
|
||||
void setCol(int column, const Vector4<S>& vector);
|
||||
Vector4<S> col(int column) const;
|
||||
|
||||
template<typename T>
|
||||
void set(const Matrix4<T>& mat);
|
||||
|
||||
Vector3<S> translation() const;
|
||||
void setTranslation(const Vector3<S>& trans);
|
||||
void translatePreMultiply(const Vector3<S>& trans);
|
||||
void translatePostMultiply(const Vector3<S>& trans);
|
||||
|
||||
bool invert();
|
||||
const Matrix4 getInverted(bool* pInvertible = NULL) const;
|
||||
S determinant() const;
|
||||
void transpose();
|
||||
const Matrix4 getTransposed() const;
|
||||
|
||||
void setFromMatrix3(const Matrix3<S>& mat3);
|
||||
Matrix3<S> toMatrix3() const;
|
||||
void toMatrix3(Matrix3<S>* mat3) const;
|
||||
|
||||
inline const S* ptr() const;
|
||||
|
||||
static Matrix4 fromTranslation(const Vector3<S>& trans);
|
||||
static Matrix4 fromRotation(Vector3<S> axis, S angle);
|
||||
static Matrix4 fromCoordSystemAxes(const Vector3<S>* xAxis, const Vector3<S>* yAxis, const Vector3<S>* zAxis);
|
||||
|
||||
public:
|
||||
static const Matrix4 IDENTITY; ///< Identity matrix
|
||||
static const Matrix4 ZERO; ///< Matrix with all zeros
|
||||
|
||||
private:
|
||||
// Constants for accessing our internal array using standard matrix notation
|
||||
static const int e00 = 0; static const int e01 = 4; static const int e02 = 8; static const int e03 = 12;
|
||||
static const int e10 = 1; static const int e11 = 5; static const int e12 = 9; static const int e13 = 13;
|
||||
static const int e20 = 2; static const int e21 = 6; static const int e22 = 10; static const int e23 = 14;
|
||||
static const int e30 = 3; static const int e31 = 7; static const int e32 = 11; static const int e33 = 15;
|
||||
|
||||
private:
|
||||
S m_v[16];
|
||||
};
|
||||
|
||||
template<typename S>
|
||||
Vector4<S> operator*(const Matrix4<S>& m, const Vector4<S>& v);
|
||||
|
||||
typedef Matrix4<float> Mat4f;
|
||||
typedef Matrix4<double> Mat4d;
|
||||
|
||||
}
|
||||
|
||||
#include "cvfMatrix4.inl"
|
||||
@@ -0,0 +1,886 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::Matrix4
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// Matrices are stored internally as a one dimensional array for performance reasons.
|
||||
///
|
||||
/// The internal indices into the 1D array are as follows:
|
||||
///
|
||||
/// <PRE>
|
||||
/// | m00 m01 m02 m03 | | 0 4 8 12 |
|
||||
/// | m10 m11 m12 m13 | | 1 5 9 13 |
|
||||
/// | m20 m21 m22 m23 | | 2 6 10 14 |
|
||||
/// | m30 m31 m32 m33 | | 3 7 11 15 |
|
||||
/// </PRE>
|
||||
///
|
||||
/// This is consistent with the way matrices are represented in %OpenGL.
|
||||
/// To exemplify, translation values are stored in elements 12,13,14; see figure below
|
||||
///
|
||||
/// <PRE>
|
||||
/// | 1 0 0 Tx |
|
||||
/// | 0 1 0 Ty |
|
||||
/// | 0 0 1 Tz |
|
||||
/// | 0 0 0 1 |
|
||||
/// </PRE>
|
||||
///
|
||||
/// From the %OpenGL red book (page 68) v' = M*v
|
||||
///
|
||||
/// <PRE>
|
||||
/// | X'| | 1 0 0 Tx | | X |
|
||||
/// | Y'| | 0 1 0 Ty | | Y |
|
||||
/// | Z'| = | 0 0 1 Tz | * | Z |
|
||||
/// | 1 | | 0 0 0 1 | | 1 |
|
||||
/// </PRE>
|
||||
///
|
||||
/// Beware when porting code that uses C style double array indexing. In this case, the first
|
||||
/// index given will corrspond to the columnd, eg M[3][0] = Tx, M[3][1] = Ty, M[3][2] = Tz
|
||||
///
|
||||
/// To ease accessing the internal 1D array in implementations, the private eij constants can be used.
|
||||
/// These are consistent with the normal row column ordering, so that e02 accesses the element
|
||||
/// in the first row and the third column.
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
template<typename S> Matrix4<S> const Matrix4<S>::IDENTITY;
|
||||
template<typename S> Matrix4<S> const Matrix4<S>::ZERO(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/// Default constructor. Initializes matrix to identity
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
Matrix4<S>::Matrix4()
|
||||
{
|
||||
setIdentity();
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/// Copy constructor
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
inline Matrix4<S>::Matrix4(const Matrix4& other)
|
||||
{
|
||||
System::memcpy(m_v, sizeof(m_v), other.m_v, sizeof(other.m_v));
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/// Constructor with explicit initialization of all matrix elements.
|
||||
///
|
||||
/// The value of the parameter \a mrc will be placed in row r and column c of the matrix, eg m23
|
||||
/// goes into row 2, column 3.
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
Matrix4<S>::Matrix4(S m00, S m01, S m02, S m03, S m10, S m11, S m12, S m13, S m20, S m21, S m22, S m23, S m30, S m31, S m32, S m33)
|
||||
{
|
||||
m_v[e00] = m00;
|
||||
m_v[e10] = m10;
|
||||
m_v[e20] = m20;
|
||||
m_v[e30] = m30;
|
||||
m_v[e01] = m01;
|
||||
m_v[e11] = m11;
|
||||
m_v[e21] = m21;
|
||||
m_v[e31] = m31;
|
||||
m_v[e02] = m02;
|
||||
m_v[e12] = m12;
|
||||
m_v[e22] = m22;
|
||||
m_v[e32] = m32;
|
||||
m_v[e03] = m03;
|
||||
m_v[e13] = m13;
|
||||
m_v[e23] = m23;
|
||||
m_v[e33] = m33;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
Matrix4<S>::Matrix4(const Matrix3<S>& other)
|
||||
{
|
||||
setFromMatrix3(other);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
template<typename T>
|
||||
Matrix4<S>::Matrix4(const T& other)
|
||||
{
|
||||
m_v[e00] = static_cast<S>(other.rowCol(0, 0));
|
||||
m_v[e10] = static_cast<S>(other.rowCol(1, 0));
|
||||
m_v[e20] = static_cast<S>(other.rowCol(2, 0));
|
||||
m_v[e30] = static_cast<S>(other.rowCol(3, 0));
|
||||
m_v[e01] = static_cast<S>(other.rowCol(0, 1));
|
||||
m_v[e11] = static_cast<S>(other.rowCol(1, 1));
|
||||
m_v[e21] = static_cast<S>(other.rowCol(2, 1));
|
||||
m_v[e31] = static_cast<S>(other.rowCol(3, 1));
|
||||
m_v[e02] = static_cast<S>(other.rowCol(0, 2));
|
||||
m_v[e12] = static_cast<S>(other.rowCol(1, 2));
|
||||
m_v[e22] = static_cast<S>(other.rowCol(2, 2));
|
||||
m_v[e32] = static_cast<S>(other.rowCol(3, 2));
|
||||
m_v[e03] = static_cast<S>(other.rowCol(0, 3));
|
||||
m_v[e13] = static_cast<S>(other.rowCol(1, 3));
|
||||
m_v[e23] = static_cast<S>(other.rowCol(2, 3));
|
||||
m_v[e33] = static_cast<S>(other.rowCol(3, 3));
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/// Assignment operator
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
inline Matrix4<S>& Matrix4<S>::operator=(const Matrix4& obj)
|
||||
{
|
||||
System::memcpy(m_v, sizeof(m_v), obj.m_v, sizeof(obj.m_v));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/// Comparison operator. Checks for equality using exact comparisons.
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
bool Matrix4<S>::operator==(const Matrix4& rhs) const
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
if (m_v[i] != rhs.m_v[i]) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/// Comparison operator. Checks for not equal using exact comparisons.
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
bool Matrix4<S>::operator!=(const Matrix4& rhs) const
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
if (m_v[i] != rhs.m_v[i]) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
const Matrix4<S> Matrix4<S>::operator*(const Matrix4& rhs) const
|
||||
{
|
||||
Matrix4 m;
|
||||
m.m_v[e00] = m_v[e00] * rhs.m_v[e00] + m_v[e01] * rhs.m_v[e10] + m_v[e02] * rhs.m_v[e20] + m_v[e03] * rhs.m_v[e30];
|
||||
m.m_v[e01] = m_v[e00] * rhs.m_v[e01] + m_v[e01] * rhs.m_v[e11] + m_v[e02] * rhs.m_v[e21] + m_v[e03] * rhs.m_v[e31];
|
||||
m.m_v[e02] = m_v[e00] * rhs.m_v[e02] + m_v[e01] * rhs.m_v[e12] + m_v[e02] * rhs.m_v[e22] + m_v[e03] * rhs.m_v[e32];
|
||||
m.m_v[e03] = m_v[e00] * rhs.m_v[e03] + m_v[e01] * rhs.m_v[e13] + m_v[e02] * rhs.m_v[e23] + m_v[e03] * rhs.m_v[e33];
|
||||
|
||||
m.m_v[e10] = m_v[e10] * rhs.m_v[e00] + m_v[e11] * rhs.m_v[e10] + m_v[e12] * rhs.m_v[e20] + m_v[e13] * rhs.m_v[e30];
|
||||
m.m_v[e11] = m_v[e10] * rhs.m_v[e01] + m_v[e11] * rhs.m_v[e11] + m_v[e12] * rhs.m_v[e21] + m_v[e13] * rhs.m_v[e31];
|
||||
m.m_v[e12] = m_v[e10] * rhs.m_v[e02] + m_v[e11] * rhs.m_v[e12] + m_v[e12] * rhs.m_v[e22] + m_v[e13] * rhs.m_v[e32];
|
||||
m.m_v[e13] = m_v[e10] * rhs.m_v[e03] + m_v[e11] * rhs.m_v[e13] + m_v[e12] * rhs.m_v[e23] + m_v[e13] * rhs.m_v[e33];
|
||||
|
||||
m.m_v[e20] = m_v[e20] * rhs.m_v[e00] + m_v[e21] * rhs.m_v[e10] + m_v[e22] * rhs.m_v[e20] + m_v[e23] * rhs.m_v[e30];
|
||||
m.m_v[e21] = m_v[e20] * rhs.m_v[e01] + m_v[e21] * rhs.m_v[e11] + m_v[e22] * rhs.m_v[e21] + m_v[e23] * rhs.m_v[e31];
|
||||
m.m_v[e22] = m_v[e20] * rhs.m_v[e02] + m_v[e21] * rhs.m_v[e12] + m_v[e22] * rhs.m_v[e22] + m_v[e23] * rhs.m_v[e32];
|
||||
m.m_v[e23] = m_v[e20] * rhs.m_v[e03] + m_v[e21] * rhs.m_v[e13] + m_v[e22] * rhs.m_v[e23] + m_v[e23] * rhs.m_v[e33];
|
||||
|
||||
m.m_v[e30] = m_v[e30] * rhs.m_v[e00] + m_v[e31] * rhs.m_v[e10] + m_v[e32] * rhs.m_v[e20] + m_v[e33] * rhs.m_v[e30];
|
||||
m.m_v[e31] = m_v[e30] * rhs.m_v[e01] + m_v[e31] * rhs.m_v[e11] + m_v[e32] * rhs.m_v[e21] + m_v[e33] * rhs.m_v[e31];
|
||||
m.m_v[e32] = m_v[e30] * rhs.m_v[e02] + m_v[e31] * rhs.m_v[e12] + m_v[e32] * rhs.m_v[e22] + m_v[e33] * rhs.m_v[e32];
|
||||
m.m_v[e33] = m_v[e30] * rhs.m_v[e03] + m_v[e31] * rhs.m_v[e13] + m_v[e32] * rhs.m_v[e23] + m_v[e33] * rhs.m_v[e33];
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
const Vector4<S> Matrix4<S>::operator*(const Vector4<S>& rhs) const
|
||||
{
|
||||
return Vector4<S>(m_v[e00]*rhs.x() + m_v[e01]*rhs.y() + m_v[e02]*rhs.z() + m_v[e03]*rhs.w(),
|
||||
m_v[e10]*rhs.x() + m_v[e11]*rhs.y() + m_v[e12]*rhs.z() + m_v[e13]*rhs.w(),
|
||||
m_v[e20]*rhs.x() + m_v[e21]*rhs.y() + m_v[e22]*rhs.z() + m_v[e23]*rhs.w(),
|
||||
m_v[e30]*rhs.x() + m_v[e31]*rhs.y() + m_v[e32]*rhs.z() + m_v[e33]*rhs.w());
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/// Sets this matrix to identity
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
void Matrix4<S>::setIdentity()
|
||||
{
|
||||
m_v[0] = 1;
|
||||
m_v[1] = 0;
|
||||
m_v[2] = 0;
|
||||
m_v[3] = 0;
|
||||
|
||||
m_v[4] = 0;
|
||||
m_v[5] = 1;
|
||||
m_v[6] = 0;
|
||||
m_v[7] = 0;
|
||||
|
||||
m_v[8] = 0;
|
||||
m_v[9] = 0;
|
||||
m_v[10] = 1;
|
||||
m_v[11] = 0;
|
||||
|
||||
m_v[12] = 0;
|
||||
m_v[13] = 0;
|
||||
m_v[14] = 0;
|
||||
m_v[15] = 1;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/// Check if this matrix is identity using exact comparisons
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
bool Matrix4<S>::isIdentity() const
|
||||
{
|
||||
if (m_v[0] != 1) return false;
|
||||
if (m_v[1] != 0) return false;
|
||||
if (m_v[2] != 0) return false;
|
||||
if (m_v[3] != 0) return false;
|
||||
|
||||
if (m_v[4] != 0) return false;
|
||||
if (m_v[5] != 1) return false;
|
||||
if (m_v[6] != 0) return false;
|
||||
if (m_v[7] != 0) return false;
|
||||
|
||||
if (m_v[8] != 0) return false;
|
||||
if (m_v[9] != 0) return false;
|
||||
if (m_v[10] != 1) return false;
|
||||
if (m_v[11] != 0) return false;
|
||||
|
||||
if (m_v[12] != 0) return false;
|
||||
if (m_v[13] != 0) return false;
|
||||
if (m_v[14] != 0) return false;
|
||||
if (m_v[15] != 1) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/// Set all matrix elements to 0
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
void Matrix4<S>::setZero()
|
||||
{
|
||||
m_v[0] = 0;
|
||||
m_v[1] = 0;
|
||||
m_v[2] = 0;
|
||||
m_v[3] = 0;
|
||||
m_v[4] = 0;
|
||||
m_v[5] = 0;
|
||||
m_v[6] = 0;
|
||||
m_v[7] = 0;
|
||||
m_v[8] = 0;
|
||||
m_v[9] = 0;
|
||||
m_v[10] = 0;
|
||||
m_v[11] = 0;
|
||||
m_v[12] = 0;
|
||||
m_v[13] = 0;
|
||||
m_v[14] = 0;
|
||||
m_v[15] = 0;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/// Returns true if all elements of the matrix are 0. Uses exact comparison.
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
bool Matrix4<S>::isZero() const
|
||||
{
|
||||
if (m_v[0] != 0) return false;
|
||||
if (m_v[1] != 0) return false;
|
||||
if (m_v[2] != 0) return false;
|
||||
if (m_v[3] != 0) return false;
|
||||
|
||||
if (m_v[4] != 0) return false;
|
||||
if (m_v[5] != 0) return false;
|
||||
if (m_v[6] != 0) return false;
|
||||
if (m_v[7] != 0) return false;
|
||||
|
||||
if (m_v[8] != 0) return false;
|
||||
if (m_v[9] != 0) return false;
|
||||
if (m_v[10] != 0) return false;
|
||||
if (m_v[11] != 0) return false;
|
||||
|
||||
if (m_v[12] != 0) return false;
|
||||
if (m_v[13] != 0) return false;
|
||||
if (m_v[14] != 0) return false;
|
||||
if (m_v[15] != 0) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/// Set the matrix element at the specified row and column
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
inline void Matrix4<S>::setRowCol(int row, int col, S value)
|
||||
{
|
||||
CVF_TIGHT_ASSERT(row >= 0 && row < 4);
|
||||
CVF_TIGHT_ASSERT(col >= 0 && col < 4);
|
||||
|
||||
m_v[4*col + row] = value;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/// Get the matrix element at the specified row and column
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
inline S Matrix4<S>::rowCol(int row, int col) const
|
||||
{
|
||||
CVF_TIGHT_ASSERT(row >= 0 && row < 4);
|
||||
CVF_TIGHT_ASSERT(col >= 0 && col < 4);
|
||||
|
||||
return m_v[4*col + row];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get modifiable reference to the the matrix element at the specified row and column
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
inline S& Matrix4<S>::operator()(int row, int col)
|
||||
{
|
||||
CVF_TIGHT_ASSERT(row >= 0 && row < 4);
|
||||
CVF_TIGHT_ASSERT(col >= 0 && col < 4);
|
||||
|
||||
return m_v[4*col + row];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the matrix element at the specified row and column
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
inline S Matrix4<S>::operator()(int row, int col) const
|
||||
{
|
||||
CVF_TIGHT_ASSERT(row >= 0 && row < 4);
|
||||
CVF_TIGHT_ASSERT(col >= 0 && col < 4);
|
||||
|
||||
return m_v[4*col + row];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
void Matrix4<S>::setRow(int row, const Vector4<S>& vector)
|
||||
{
|
||||
CVF_TIGHT_ASSERT(row >= 0 && row < 4);
|
||||
|
||||
m_v[row] = vector.x();
|
||||
m_v[row + 4] = vector.y();
|
||||
m_v[row + 8] = vector.z();
|
||||
m_v[row + 12] = vector.w();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
Vector4<S> Matrix4<S>::row(int row) const
|
||||
{
|
||||
CVF_TIGHT_ASSERT(row >= 0 && row < 4);
|
||||
|
||||
return Vector4<S>(m_v[row], m_v[row + 4], m_v[row + 8], m_v[row + 12]);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
void Matrix4<S>::setCol(int column, const Vector4<S>& vector)
|
||||
{
|
||||
CVF_TIGHT_ASSERT(column >= 0 && column < 4);
|
||||
|
||||
m_v[4*column] = vector.x();
|
||||
m_v[4*column + 1] = vector.y();
|
||||
m_v[4*column + 2] = vector.z();
|
||||
m_v[4*column + 3] = vector.w();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
Vector4<S> Matrix4<S>::col(int column) const
|
||||
{
|
||||
CVF_TIGHT_ASSERT(column >= 0 && column < 4);
|
||||
|
||||
return Vector4<S>(m_v[4*column], m_v[4*column + 1], m_v[4*column + 2], m_v[4*column + 3]);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
template<typename T>
|
||||
void Matrix4<S>::set(const Matrix4<T>& mat)
|
||||
{
|
||||
const T* matPtr = mat.ptr();
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
m_v[i] = static_cast<S>(matPtr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/// Extracts the translation part of the transformation matrix
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
Vector3<S> Matrix4<S>::translation() const
|
||||
{
|
||||
return Vector3<S>(m_v[e03], m_v[e13], m_v[e23]);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/// Sets the translation transformation part of the matrix
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
void Matrix4<S>::setTranslation(const Vector3<S>& trans)
|
||||
{
|
||||
m_v[e03] = trans.x();
|
||||
m_v[e13] = trans.y();
|
||||
m_v[e23] = trans.z();
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/// Adds translation by pre-multiplying the matrix with a matrix containing the specified translation
|
||||
///
|
||||
/// Adds translation to this (transformation) matrix by pre multiplying the current matrix M with
|
||||
/// a matrix containing the specified translation. Calling this function has the effect of doing the
|
||||
/// multiplication T x M where T is a matrix that only contains translation.
|
||||
///
|
||||
/// \param trans Specifies the X, Y and Z components of the translation.
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
void Matrix4<S>::translatePreMultiply(const Vector3<S>& trans)
|
||||
{
|
||||
m_v[e00] += trans.x()*m_v[e30];
|
||||
m_v[e01] += trans.x()*m_v[e31];
|
||||
m_v[e02] += trans.x()*m_v[e32];
|
||||
m_v[e03] += trans.x()*m_v[e33];
|
||||
|
||||
m_v[e10] += trans.y()*m_v[e30];
|
||||
m_v[e11] += trans.y()*m_v[e31];
|
||||
m_v[e12] += trans.y()*m_v[e32];
|
||||
m_v[e13] += trans.y()*m_v[e33];
|
||||
|
||||
m_v[e20] += trans.z()*m_v[e30];
|
||||
m_v[e21] += trans.z()*m_v[e31];
|
||||
m_v[e22] += trans.z()*m_v[e32];
|
||||
m_v[e23] += trans.z()*m_v[e33];
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/// Adds translation by post-multiplying the matrix with a matrix containing the specified translation
|
||||
///
|
||||
/// Adds translation to this (transformation) matrix by post multiplying the current matrix M with
|
||||
/// a matrix containing the specified translation. Calling this function has the effect of doing the
|
||||
/// multiplication M x T where T is a matrix that only contains translation.
|
||||
///
|
||||
/// \param trans Specifies the X, Y and Z coordinates of the translation.
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
void Matrix4<S>::translatePostMultiply(const Vector3<S>& trans)
|
||||
{
|
||||
m_v[e03] += trans.x()*m_v[e00] + trans.y()*m_v[e01] + trans.z()*m_v[e02];
|
||||
m_v[e13] += trans.x()*m_v[e10] + trans.y()*m_v[e11] + trans.z()*m_v[e12];
|
||||
m_v[e23] += trans.x()*m_v[e20] + trans.y()*m_v[e21] + trans.z()*m_v[e22];
|
||||
m_v[e33] += trans.x()*m_v[e30] + trans.y()*m_v[e31] + trans.z()*m_v[e32];
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
bool Matrix4<S>::invert()
|
||||
{
|
||||
// Use double internally here
|
||||
const double m00 = static_cast<double>(m_v[e00]);
|
||||
const double m10 = static_cast<double>(m_v[e10]);
|
||||
const double m20 = static_cast<double>(m_v[e20]);
|
||||
const double m30 = static_cast<double>(m_v[e30]);
|
||||
const double m01 = static_cast<double>(m_v[e01]);
|
||||
const double m11 = static_cast<double>(m_v[e11]);
|
||||
const double m21 = static_cast<double>(m_v[e21]);
|
||||
const double m31 = static_cast<double>(m_v[e31]);
|
||||
const double m02 = static_cast<double>(m_v[e02]);
|
||||
const double m12 = static_cast<double>(m_v[e12]);
|
||||
const double m22 = static_cast<double>(m_v[e22]);
|
||||
const double m32 = static_cast<double>(m_v[e32]);
|
||||
const double m03 = static_cast<double>(m_v[e03]);
|
||||
const double m13 = static_cast<double>(m_v[e13]);
|
||||
const double m23 = static_cast<double>(m_v[e23]);
|
||||
const double m33 = static_cast<double>(m_v[e33]);
|
||||
|
||||
const double s0 = m00 * m11 - m01 * m10;
|
||||
const double s1 = m00 * m12 - m02 * m10;
|
||||
const double s2 = m00 * m13 - m03 * m10;
|
||||
const double s3 = m01 * m12 - m02 * m11;
|
||||
const double s4 = m01 * m13 - m03 * m11;
|
||||
const double s5 = m02 * m13 - m03 * m12;
|
||||
|
||||
const double c5 = m22 * m33 - m23 * m32;
|
||||
const double c4 = m21 * m33 - m23 * m31;
|
||||
const double c3 = m21 * m32 - m22 * m31;
|
||||
const double c2 = m20 * m33 - m23 * m30;
|
||||
const double c1 = m20 * m32 - m22 * m30;
|
||||
const double c0 = m20 * m31 - m21 * m30;
|
||||
|
||||
const double det = s0*c5 - s1*c4 + s2*c3 + s3*c2 - s4*c1 + s5*c0;
|
||||
|
||||
if (Math::abs(det) > std::numeric_limits<double>::epsilon())
|
||||
{
|
||||
const double invDet = 1/det;
|
||||
|
||||
m_v[e00] = static_cast<S>( ( m11 * c5 - m12 * c4 + m13 * c3 ) * invDet );
|
||||
m_v[e10] = static_cast<S>( ( - m10 * c5 + m12 * c2 - m13 * c1 ) * invDet );
|
||||
m_v[e20] = static_cast<S>( ( m10 * c4 - m11 * c2 + m13 * c0 ) * invDet );
|
||||
m_v[e30] = static_cast<S>( ( - m10 * c3 + m11 * c1 - m12 * c0 ) * invDet );
|
||||
m_v[e01] = static_cast<S>( ( - m01 * c5 + m02 * c4 - m03 * c3 ) * invDet );
|
||||
m_v[e11] = static_cast<S>( ( m00 * c5 - m02 * c2 + m03 * c1 ) * invDet );
|
||||
m_v[e21] = static_cast<S>( ( - m00 * c4 + m01 * c2 - m03 * c0 ) * invDet );
|
||||
m_v[e31] = static_cast<S>( ( m00 * c3 - m01 * c1 + m02 * c0 ) * invDet );
|
||||
m_v[e02] = static_cast<S>( ( m31 * s5 - m32 * s4 + m33 * s3 ) * invDet );
|
||||
m_v[e12] = static_cast<S>( ( - m30 * s5 + m32 * s2 - m33 * s1 ) * invDet );
|
||||
m_v[e22] = static_cast<S>( ( m30 * s4 - m31 * s2 + m33 * s0 ) * invDet );
|
||||
m_v[e32] = static_cast<S>( ( - m30 * s3 + m31 * s1 - m32 * s0 ) * invDet );
|
||||
m_v[e03] = static_cast<S>( ( - m21 * s5 + m22 * s4 - m23 * s3 ) * invDet );
|
||||
m_v[e13] = static_cast<S>( ( m20 * s5 - m22 * s2 + m23 * s1 ) * invDet );
|
||||
m_v[e23] = static_cast<S>( ( - m20 * s4 + m21 * s2 - m23 * s0 ) * invDet );
|
||||
m_v[e33] = static_cast<S>( ( m20 * s3 - m21 * s1 + m22 * s0 ) * invDet );
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
const Matrix4<S> Matrix4<S>::getInverted(bool* pInvertible) const
|
||||
{
|
||||
Matrix4 m(*this);
|
||||
if (m.invert())
|
||||
{
|
||||
if (pInvertible) *pInvertible = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pInvertible) *pInvertible = false;
|
||||
m.setZero();
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
S Matrix4<S>::determinant() const
|
||||
{
|
||||
// Consider using double precision for the intermediate calculations here
|
||||
// Haven't seen any direct need for it yet, but good old GLview API did that
|
||||
const S a0 = m_v[e00]*m_v[e11] - m_v[e01]*m_v[e10];
|
||||
const S a1 = m_v[e00]*m_v[e12] - m_v[e02]*m_v[e10];
|
||||
const S a2 = m_v[e00]*m_v[e13] - m_v[e03]*m_v[e10];
|
||||
const S a3 = m_v[e01]*m_v[e12] - m_v[e02]*m_v[e11];
|
||||
const S a4 = m_v[e01]*m_v[e13] - m_v[e03]*m_v[e11];
|
||||
const S a5 = m_v[e02]*m_v[e13] - m_v[e03]*m_v[e12];
|
||||
|
||||
const S b0 = m_v[e20]*m_v[e31] - m_v[e21]*m_v[e30];
|
||||
const S b1 = m_v[e20]*m_v[e32] - m_v[e22]*m_v[e30];
|
||||
const S b2 = m_v[e20]*m_v[e33] - m_v[e23]*m_v[e30];
|
||||
const S b3 = m_v[e21]*m_v[e32] - m_v[e22]*m_v[e31];
|
||||
const S b4 = m_v[e21]*m_v[e33] - m_v[e23]*m_v[e31];
|
||||
const S b5 = m_v[e22]*m_v[e33] - m_v[e23]*m_v[e32];
|
||||
|
||||
return (a0*b5 - a1*b4 + a2*b3 + a3*b2 - a4*b1 + a5*b0);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
void Matrix4<S>::transpose()
|
||||
{
|
||||
S tmp;
|
||||
int i, j;
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
for (j = i + 1; j < 4; j++)
|
||||
{
|
||||
tmp = m_v[j + 4*i];
|
||||
m_v[j + 4*i] = m_v[4*j + i];
|
||||
m_v[4*j + i] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
const Matrix4<S> Matrix4<S>::getTransposed() const
|
||||
{
|
||||
Matrix4 m(*this);
|
||||
m.transpose();
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
void Matrix4<S>::setFromMatrix3(const Matrix3<S>& mat3)
|
||||
{
|
||||
m_v[e00] = mat3.rowCol(0, 0);
|
||||
m_v[e01] = mat3.rowCol(0, 1);
|
||||
m_v[e02] = mat3.rowCol(0, 2);
|
||||
m_v[e03] = 0;
|
||||
m_v[e10] = mat3.rowCol(1, 0);
|
||||
m_v[e11] = mat3.rowCol(1, 1);
|
||||
m_v[e12] = mat3.rowCol(1, 2);
|
||||
m_v[e13] = 0;
|
||||
m_v[e20] = mat3.rowCol(2, 0);
|
||||
m_v[e21] = mat3.rowCol(2, 1);
|
||||
m_v[e22] = mat3.rowCol(2, 2);
|
||||
m_v[e23] = 0;
|
||||
m_v[e30] = 0;
|
||||
m_v[e31] = 0;
|
||||
m_v[e32] = 0;
|
||||
m_v[e33] = 1;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
Matrix3<S> Matrix4<S>::toMatrix3() const
|
||||
{
|
||||
return Matrix3<S>(m_v[e00], m_v[e01], m_v[e02],
|
||||
m_v[e10], m_v[e11], m_v[e12],
|
||||
m_v[e20], m_v[e21], m_v[e22]);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
void Matrix4<S>::toMatrix3(Matrix3<S>* mat3) const
|
||||
{
|
||||
CVF_ASSERT(mat3);
|
||||
mat3->setRowCol(0, 0, m_v[e00]);
|
||||
mat3->setRowCol(0, 1, m_v[e01]);
|
||||
mat3->setRowCol(0, 2, m_v[e02]);
|
||||
mat3->setRowCol(1, 0, m_v[e10]);
|
||||
mat3->setRowCol(1, 1, m_v[e11]);
|
||||
mat3->setRowCol(1, 2, m_v[e12]);
|
||||
mat3->setRowCol(2, 0, m_v[e20]);
|
||||
mat3->setRowCol(2, 1, m_v[e21]);
|
||||
mat3->setRowCol(2, 2, m_v[e22]);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
const S* Matrix4<S>::ptr() const
|
||||
{
|
||||
return m_v;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/// Static member function that creates a transformation matrix containing only translation
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
Matrix4<S> Matrix4<S>::fromTranslation(const Vector3<S>& trans)
|
||||
{
|
||||
return Matrix4(1, 0, 0, trans.x(),
|
||||
0, 1, 0, trans.y(),
|
||||
0, 0, 1, trans.z(),
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
Matrix4<S> Matrix4<S>::fromRotation(Vector3<S> axis, S angle)
|
||||
{
|
||||
axis.normalize();
|
||||
|
||||
S rcos = Math::cos(angle);
|
||||
S rsin = Math::sin(angle);
|
||||
|
||||
Matrix4 m;
|
||||
m.m_v[e00] = rcos + axis.x()*axis.x()*(1 - rcos);
|
||||
m.m_v[e10] = axis.z() * rsin + axis.y()*axis.x()*(1 - rcos);
|
||||
m.m_v[e20] = -axis.y() * rsin + axis.z()*axis.x()*(1 - rcos);
|
||||
m.m_v[e01] = -axis.z() * rsin + axis.x()*axis.y()*(1 - rcos);
|
||||
m.m_v[e11] = rcos + axis.y()*axis.y()*(1 - rcos);
|
||||
m.m_v[e21] = axis.x() * rsin + axis.z()*axis.y()*(1 - rcos);
|
||||
m.m_v[e02] = axis.y() * rsin + axis.x()*axis.z()*(1 - rcos);
|
||||
m.m_v[e12] = -axis.x() * rsin + axis.y()*axis.z()*(1 - rcos);
|
||||
m.m_v[e22] = rcos + axis.z()*axis.z()*(1 - rcos);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/// Create a rotation matrix that will align the global X, Y and Z axes with the specified axes.
|
||||
///
|
||||
/// Note that at least one axis must be specified and all specified axes must be normalized.
|
||||
/// If two or three axes are specified, they must be orthogonal to each other.
|
||||
///
|
||||
/// \param xAxis Orientation of x axis
|
||||
/// \param yAxis Orientation of y axis
|
||||
/// \param zAxis Orientation of z axis
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
Matrix4<S> Matrix4<S>::fromCoordSystemAxes(const Vector3<S>* xAxis, const Vector3<S>* yAxis, const Vector3<S>* zAxis)
|
||||
{
|
||||
Vector3<S> x(0, 0, 0);
|
||||
Vector3<S> y(0, 0, 0);
|
||||
Vector3<S> z(0, 0, 0);
|
||||
|
||||
if (xAxis && yAxis && zAxis)
|
||||
{
|
||||
x = *xAxis;
|
||||
y = *yAxis;
|
||||
z = *zAxis;
|
||||
}
|
||||
else if (xAxis && yAxis)
|
||||
{
|
||||
x = *xAxis;
|
||||
y = *yAxis;
|
||||
z = x ^ y;
|
||||
}
|
||||
else if (xAxis && zAxis)
|
||||
{
|
||||
x = *xAxis;
|
||||
z = *zAxis;
|
||||
y = z ^ x;
|
||||
}
|
||||
else if (yAxis && zAxis)
|
||||
{
|
||||
y = *yAxis;
|
||||
z = *zAxis;
|
||||
x = y ^ z;
|
||||
}
|
||||
else if (xAxis)
|
||||
{
|
||||
xAxis->createOrthonormalBasis(0, &x, &y, &z);
|
||||
}
|
||||
else if (yAxis)
|
||||
{
|
||||
yAxis->createOrthonormalBasis(1, &x, &y, &z);
|
||||
}
|
||||
else if (zAxis)
|
||||
{
|
||||
zAxis->createOrthonormalBasis(2, &x, &y, &z);
|
||||
}
|
||||
else
|
||||
{
|
||||
CVF_FAIL_MSG("Must specify at least one axis");
|
||||
}
|
||||
|
||||
Matrix4 m;
|
||||
m.setIdentity();
|
||||
m.setCol(0, Vector4<S>(x, 0));
|
||||
m.setCol(1, Vector4<S>(y, 0));
|
||||
m.setCol(2, Vector4<S>(z, 0));
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Post multiplication: matrix * column vector
|
||||
///
|
||||
/// v' = M*v
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
cvf::Vector4<S> operator*(const cvf::Matrix4<S>& m, const cvf::Vector4<S>& v)
|
||||
{
|
||||
cvf::Vector4<S> vec(
|
||||
v.x()*m.rowCol(0,0) + v.y()*m.rowCol(0,1) + v.z()*m.rowCol(0,2) + v.w()*m.rowCol(0,3),
|
||||
v.x()*m.rowCol(1,0) + v.y()*m.rowCol(1,1) + v.z()*m.rowCol(1,2) + v.w()*m.rowCol(1,3),
|
||||
v.x()*m.rowCol(2,0) + v.y()*m.rowCol(2,1) + v.z()*m.rowCol(2,2) + v.w()*m.rowCol(2,3),
|
||||
v.x()*m.rowCol(3,0) + v.y()*m.rowCol(3,1) + v.z()*m.rowCol(3,2) + v.w()*m.rowCol(3,3)
|
||||
);
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfObject.h"
|
||||
#include "cvfTrace.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::Object
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// Base class for all reference counted objects
|
||||
///
|
||||
/// Very often used in conjunction with the ref<> class (smart pointer) which wraps the
|
||||
/// reference counting. Thus direct use of addRef() and release() is seldom needed.
|
||||
///
|
||||
/// The copy constructor and assignment operator is disabled by default so you will get compiler errors
|
||||
/// instead of unexpected behavior if you pass objects (that derive from Object) by value or assign objects.
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the set of currently active/allocated object instances
|
||||
///
|
||||
/// Note that unless the define CVF_TRACK_ACTIVE_OBJECT_INSTANCES is set to 1, this function
|
||||
/// will always return an empty set.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<Object*>* Object::activeObjectInstances()
|
||||
{
|
||||
static std::set<Object*>* sl_activeObjects = NULL;
|
||||
if (!sl_activeObjects)
|
||||
{
|
||||
sl_activeObjects = new std::set<Object*>;
|
||||
}
|
||||
|
||||
return sl_activeObjects;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Dump list of active object instances using Trace class
|
||||
///
|
||||
/// Currently this function utilizes RTTI and typeid to get the class names.
|
||||
/// Data on active instances will only be present if CVF_TRACK_ACTIVE_OBJECT_INSTANCES is defined
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void Object::dumpActiveObjectInstances()
|
||||
{
|
||||
Trace::show("Dumping active object instances:");
|
||||
|
||||
std::set<Object*>* objInstances = Object::activeObjectInstances();
|
||||
size_t numInstances = objInstances->size();
|
||||
|
||||
#if ((CVF_TRACK_ACTIVE_OBJECT_INSTANCES >= 1 && defined(_DEBUG)) || CVF_TRACK_ACTIVE_OBJECT_INSTANCES == 2)
|
||||
|
||||
// Use a map to count the number of occurences of each class
|
||||
std::map<std::string, int> occurences;
|
||||
|
||||
std::set<Object*>::iterator it;
|
||||
for (it = objInstances->begin(); it != objInstances->end(); ++it)
|
||||
{
|
||||
Object* obj = *it;
|
||||
|
||||
const type_info& typeInfo = typeid(*obj);
|
||||
const char* className = typeInfo.name();
|
||||
if (occurences.find(className) != occurences.end())
|
||||
{
|
||||
occurences[className] += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
occurences[className] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (occurences.size() > 0)
|
||||
{
|
||||
std::map<std::string, int>::iterator it;
|
||||
for (it = occurences.begin(); it != occurences.end(); ++it)
|
||||
{
|
||||
Trace::show("%6d instances of: %s", it->second, it->first.data());
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
Trace::show(" Tracking of active instances not enabled!");
|
||||
|
||||
#endif
|
||||
|
||||
Trace::show("Total number of active object instances: %d", numInstances);
|
||||
}
|
||||
|
||||
|
||||
} // namespace cvf
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfSystem.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Base class for all reference counted objects
|
||||
//
|
||||
//==================================================================================================
|
||||
class Object
|
||||
{
|
||||
public:
|
||||
inline Object();
|
||||
inline virtual ~Object();
|
||||
|
||||
inline int addRef() const;
|
||||
inline int release() const;
|
||||
inline int refCount() const;
|
||||
|
||||
// Helpers for debugging, see the CVF_TRACK_ACTIVE_OBJECT_INSTANCES define
|
||||
static std::set<Object*>* activeObjectInstances();
|
||||
static void dumpActiveObjectInstances();
|
||||
|
||||
private:
|
||||
mutable int m_refCount;
|
||||
|
||||
CVF_DISABLE_COPY_AND_ASSIGN(Object);
|
||||
};
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Smart pointer class
|
||||
//
|
||||
//==================================================================================================
|
||||
template <typename T>
|
||||
class ref
|
||||
{
|
||||
public:
|
||||
ref(T* object = NULL);
|
||||
ref(const ref& other);
|
||||
template<typename T2> ref(const ref<T2>& other);
|
||||
~ref();
|
||||
|
||||
ref& operator=(T* rhs);
|
||||
ref& operator=(ref rhs);
|
||||
template<typename T2> ref& operator=(const ref<T2>& rhs);
|
||||
|
||||
inline T* operator->();
|
||||
inline const T* operator->() const;
|
||||
inline T& operator*();
|
||||
inline const T& operator*() const;
|
||||
inline T* p();
|
||||
inline const T* p() const;
|
||||
inline bool isNull() const;
|
||||
inline bool notNull() const;
|
||||
|
||||
bool operator<(const ref& rhs) const;
|
||||
|
||||
void swap(ref& other);
|
||||
|
||||
private:
|
||||
T* m_object;
|
||||
};
|
||||
|
||||
/// \relates cvf::ref
|
||||
/// @{
|
||||
|
||||
template<typename T1, typename T2> inline bool operator==(const ref<T1>& a, const ref<T2>& b) { return a.p() == b.p(); } ///< Returns true if the internal pointers of refs \a a and \a b are equal.
|
||||
template<typename T1, typename T2> inline bool operator!=(const ref<T1>& a, const ref<T2>& b) { return a.p() != b.p(); } ///< Returns true if the internal pointers of refs \a a and \a b are different.
|
||||
template<typename T1, typename T2> inline bool operator==(const ref<T1>& a, T2* b) { return a.p() == b; } ///< Returns true if the internal pointer of ref \a a is equal to the naked pointer \a b.
|
||||
template<typename T1, typename T2> inline bool operator!=(const ref<T1>& a, T2* b) { return a.p() != b; } ///< Returns true if the internal pointer of ref \a a is different from the naked pointer \a b.
|
||||
template<typename T1, typename T2> inline bool operator==(T1* a, const ref<T2>& b) { return a == b.p(); } ///< Returns true if the naked pointer \a a is equal to the internal pointer of ref \a b.
|
||||
template<typename T1, typename T2> inline bool operator!=(T1* a, const ref<T2>& b) { return a != b.p(); } ///< Returns true if the naked pointer \a a is different from the internal pointer of ref \a b.
|
||||
|
||||
/// Swap contents of \a a and \a b. Matches signature of std::swap().
|
||||
/// \todo Need to investigate which STL algorithms actually utilize the swap() function.
|
||||
template<typename T> inline void swap(ref<T>& a, ref<T>& b) { a.swap(b); }
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Smart pointer class for const pointers
|
||||
//
|
||||
//==================================================================================================
|
||||
template <typename T>
|
||||
class cref
|
||||
{
|
||||
public:
|
||||
cref(const T* object = NULL);
|
||||
cref(const cref& other);
|
||||
template<typename T2> cref(const cref<T2>& other);
|
||||
~cref();
|
||||
|
||||
cref& operator=(const T* rhs);
|
||||
cref& operator=(cref rhs);
|
||||
template<typename T2> cref& operator=(const cref<T2>& rhs);
|
||||
|
||||
inline const T* operator->() const;
|
||||
inline const T& operator*() const;
|
||||
inline const T* p() const;
|
||||
inline bool isNull() const;
|
||||
inline bool notNull() const;
|
||||
|
||||
bool operator<(const cref& rhs) const;
|
||||
|
||||
void swap(cref& other);
|
||||
|
||||
private:
|
||||
const T* m_object;
|
||||
};
|
||||
|
||||
/// \relates cvf::cref
|
||||
/// @{
|
||||
|
||||
template<typename T1, typename T2> inline bool operator==(const cref<T1>& a, const cref<T2>& b) { return a.p() == b.p(); } ///< Returns true if the internal pointers of refs \a a and \a b are equal.
|
||||
template<typename T1, typename T2> inline bool operator!=(const cref<T1>& a, const cref<T2>& b) { return a.p() != b.p(); } ///< Returns true if the internal pointers of refs \a a and \a b are different.
|
||||
template<typename T1, typename T2> inline bool operator==(const cref<T1>& a, T2* b) { return a.p() == b; } ///< Returns true if the internal pointer of ref \a a is equal to the naked pointer \a b.
|
||||
template<typename T1, typename T2> inline bool operator!=(const cref<T1>& a, T2* b) { return a.p() != b; } ///< Returns true if the internal pointer of ref \a a is different from the naked pointer \a b.
|
||||
template<typename T1, typename T2> inline bool operator==(T1* a, const cref<T2>& b) { return a == b.p(); } ///< Returns true if the naked pointer \a a is equal to the internal pointer of ref \a b.
|
||||
template<typename T1, typename T2> inline bool operator!=(T1* a, const cref<T2>& b) { return a != b.p(); } ///< Returns true if the naked pointer \a a is different from the internal pointer of ref \a b.
|
||||
|
||||
/// @}
|
||||
|
||||
}
|
||||
|
||||
#include "cvfObject.inl"
|
||||
@@ -0,0 +1,559 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Constructor. Set the ref count to zero
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
inline Object::Object()
|
||||
: m_refCount(0)
|
||||
{
|
||||
#if ((CVF_TRACK_ACTIVE_OBJECT_INSTANCES >= 1 && defined(_DEBUG)) || CVF_TRACK_ACTIVE_OBJECT_INSTANCES == 2)
|
||||
activeObjectInstances()->insert(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Destructor. Asserts that the ref count is zero.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
inline Object::~Object()
|
||||
{
|
||||
CVF_ASSERT(m_refCount == 0);
|
||||
|
||||
#if ((CVF_TRACK_ACTIVE_OBJECT_INSTANCES >= 1 && defined(_DEBUG)) || CVF_TRACK_ACTIVE_OBJECT_INSTANCES == 2)
|
||||
activeObjectInstances()->erase(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Increments reference count.
|
||||
///
|
||||
/// \return The new reference count.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
inline int Object::addRef() const
|
||||
{
|
||||
CVF_TIGHT_ASSERT(this);
|
||||
return ++m_refCount;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Decrements the reference count. Returns the new reference count.
|
||||
///
|
||||
/// \return The new reference count.
|
||||
///
|
||||
/// If the new reference count is zero, the object (this) is deleted.\n
|
||||
/// Legal to call on NULL objects, will then return zero.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
inline int Object::release() const
|
||||
{
|
||||
// Release on a NULL object ok, just return 0
|
||||
// This is symmetric with being able to call delete on a NULL pointer
|
||||
if (!this) return 0;
|
||||
|
||||
CVF_TIGHT_ASSERT(m_refCount > 0);
|
||||
|
||||
m_refCount--;
|
||||
|
||||
if (m_refCount == 0)
|
||||
{
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_refCount;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns the current reference count
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
inline int Object::refCount() const
|
||||
{
|
||||
CVF_TIGHT_ASSERT(this);
|
||||
return m_refCount;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::ref
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// Smart pointer class used for handling reference counted objects (that derive from Object).
|
||||
///
|
||||
/// The ref<T> class encapsulates reference counting by calling Object::addRef() and Object::release()
|
||||
/// on the internally stored object pointer.
|
||||
///
|
||||
/// \internal Inspired by boost's intrusive_ptr class.
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Constructor from naked pointer
|
||||
///
|
||||
/// Will call addRef() on the passed object.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
ref<T>::ref(T* object)
|
||||
{
|
||||
if (object)
|
||||
{
|
||||
object->addRef();
|
||||
m_object = object;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_object = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Copy constructor
|
||||
///
|
||||
/// Copies the internal pointer from the passed ref object and calls addRef() on the object.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
ref<T>::ref(const ref& other)
|
||||
{
|
||||
if (other.m_object)
|
||||
{
|
||||
other.m_object->addRef();
|
||||
m_object = other.m_object;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_object = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Construct from related.
|
||||
///
|
||||
/// Copies the internal pointer from the passed ref object and calls addRef() on the object.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
template<typename T2>
|
||||
ref<T>::ref(const ref<T2>& other)
|
||||
{
|
||||
if (other.notNull())
|
||||
{
|
||||
other->addRef();
|
||||
|
||||
// Escape const
|
||||
m_object = const_cast<T2*>(other.p());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_object = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Destructor.
|
||||
///
|
||||
/// Will call release() on the internal pointer.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
ref<T>::~ref()
|
||||
{
|
||||
if (m_object)
|
||||
{
|
||||
m_object->release();
|
||||
m_object = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Assignment from raw pointer.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
ref<T>& ref<T>::operator=(T* rhs)
|
||||
{
|
||||
// Copy-and-swap (on temporary obj)
|
||||
ref<T>(rhs).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Assignment operator
|
||||
///
|
||||
/// Copies the internal pointer from \a rhs and calls addRef().
|
||||
/// If we're already storing an internal pointer, this pointer will be release()'ed.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
ref<T>& ref<T>::operator=(ref rhs)
|
||||
{
|
||||
// Copy-and-swap (copy already done since parameter is passed by value)
|
||||
rhs.swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Assignment from related.
|
||||
///
|
||||
/// Copies the internal pointer from \a rhs and calls addRef().
|
||||
/// If we're already storing an internal pointer, this pointer will be release()'ed.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
template<typename T2>
|
||||
ref<T>& ref<T>::operator=(const ref<T2>& rhs)
|
||||
{
|
||||
// Copy-and-swap (on temporary obj)
|
||||
ref<T>(rhs).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns the naked pointer this object is associated with.
|
||||
///
|
||||
/// Added to be able to write the same code for smart pointers as for normal naked pointers.
|
||||
///
|
||||
/// \code
|
||||
/// ref<MyObject> myObject = new MyObject;
|
||||
/// myObject->doSomething(); // Easier than myObject.p()->doSomething()
|
||||
/// \endcode
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
inline T* ref<T>::operator->()
|
||||
{
|
||||
CVF_TIGHT_ASSERT(m_object);
|
||||
return m_object;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns naked const pointer this object is associated with.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
inline const T* ref<T>::operator->() const
|
||||
{
|
||||
CVF_TIGHT_ASSERT(m_object);
|
||||
return m_object;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Dereference operator returning a modifiable reference to the associated object.
|
||||
///
|
||||
/// Added to be able to write the same code for smart pointers as for normal naked pointers.
|
||||
/// \code
|
||||
/// ref<MyObject> myObject = new MyObject;
|
||||
/// *myObject.doSomething();
|
||||
/// \endcode
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
inline T& ref<T>::operator*()
|
||||
{
|
||||
CVF_TIGHT_ASSERT(m_object);
|
||||
return *m_object;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Dereference operator returning a const reference to the associated object.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
inline const T& ref<T>::operator*() const
|
||||
{
|
||||
CVF_TIGHT_ASSERT(m_object);
|
||||
return *m_object;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns the naked pointer
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
inline T* ref<T>::p()
|
||||
{
|
||||
return m_object;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns naked const pointer
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
inline const T* ref<T>::p() const
|
||||
{
|
||||
return m_object;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns true if the internal pointer is NULL
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
inline bool ref<T>::isNull() const
|
||||
{
|
||||
return m_object == NULL;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns true if the internal pointer is different from NULL
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
inline bool ref<T>::notNull() const
|
||||
{
|
||||
return m_object != NULL;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Does less than comparison of two ref objects.
|
||||
///
|
||||
/// \return Returns true if this object's internal pointer is less than the internal pointer of \a rhs.
|
||||
///
|
||||
/// The comparison is done by comparing the internal pointer values ( this.p() < rhs.p() )
|
||||
/// This operator is used in several STL collections (e.g. std::set) as well as in many STL algorithms
|
||||
/// (e.g. std::sort() ).
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
bool ref<T>::operator<(const ref& rhs) const
|
||||
{
|
||||
CVF_TIGHT_ASSERT((m_object != NULL) && (rhs.p() != NULL));
|
||||
return std::less<T*>()(m_object, rhs.m_object);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Exchanges the contents of the two smart pointers.
|
||||
///
|
||||
/// \param other Modifiable reference to the ref object that should have its contents swapped.
|
||||
///
|
||||
/// Swap the associated pointer in this and the passed ref object. Will not modify the reference
|
||||
/// count of any of the associated objects.
|
||||
///
|
||||
/// \warning Note that signature differs from normal CeeVizFramework practice. This is done to be
|
||||
/// consistent with the signature of std::swap()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void ref<T>::swap(ref& other)
|
||||
{
|
||||
T* tmp = other.m_object;
|
||||
other.m_object = m_object;
|
||||
m_object = tmp;
|
||||
}
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::cref
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// Smart pointer class used for handling const reference counted objects
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Construct from naked pointer
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
cref<T>::cref(const T* object)
|
||||
{
|
||||
if (object)
|
||||
{
|
||||
object->addRef();
|
||||
m_object = object;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_object = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Copy constructor
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
cref<T>::cref(const cref& other)
|
||||
{
|
||||
if (other.m_object)
|
||||
{
|
||||
other.m_object->addRef();
|
||||
m_object = other.m_object;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_object = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Construct from related
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
template<typename T2>
|
||||
cref<T>::cref(const cref<T2>& other)
|
||||
{
|
||||
if (other.notNull())
|
||||
{
|
||||
other->addRef();
|
||||
m_object = other.p();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_object = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
cref<T>::~cref()
|
||||
{
|
||||
if (m_object)
|
||||
{
|
||||
m_object->release();
|
||||
m_object = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
cref<T>& cref<T>::operator=(const T* rhs)
|
||||
{
|
||||
// Copy-and-swap (on temporary obj)
|
||||
cref<T>(rhs).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
cref<T>& cref<T>::operator=(cref rhs)
|
||||
{
|
||||
// Copy-and-swap (copy already done since parameter is passed by value)
|
||||
rhs.swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
template<typename T2>
|
||||
cref<T>& cref<T>::operator=(const cref<T2>& rhs)
|
||||
{
|
||||
// Copy-and-swap (on temporary obj)
|
||||
cref<T>(rhs).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
inline const T* cref<T>::operator->() const
|
||||
{
|
||||
CVF_TIGHT_ASSERT(m_object);
|
||||
return m_object;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
inline const T& cref<T>::operator*() const
|
||||
{
|
||||
CVF_TIGHT_ASSERT(m_object);
|
||||
return *m_object;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
inline const T* cref<T>::p() const
|
||||
{
|
||||
return m_object;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
inline bool cref<T>::isNull() const
|
||||
{
|
||||
return m_object == NULL;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
inline bool cref<T>::notNull() const
|
||||
{
|
||||
return m_object != NULL;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
bool cref<T>::operator<(const cref& rhs) const
|
||||
{
|
||||
CVF_TIGHT_ASSERT((m_object != NULL) && (rhs.p() != NULL));
|
||||
return std::less<const T*>()(m_object, rhs.m_object);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void cref<T>::swap(cref& other)
|
||||
{
|
||||
const T* tmp = other.m_object;
|
||||
other.m_object = m_object;
|
||||
m_object = tmp;
|
||||
}
|
||||
|
||||
|
||||
} // namespace cvf
|
||||
|
||||
@@ -0,0 +1,430 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfPlane.h"
|
||||
#include "cvfMath.h"
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::Plane
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// Class defining a plane in space
|
||||
///
|
||||
/// The class describes a plane by the equation: \f$Ax + By + Cz + Dx = 0\f$
|
||||
/// The plane's normal is defined by the coefficients \f$[A, B, C]\f$
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Default constructor
|
||||
///
|
||||
/// The plane will be set to invalid
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Plane::Plane()
|
||||
{
|
||||
// Invalidate plane coefficients
|
||||
// Note: Coefficients set to zero will still comply with the line equation but
|
||||
// the normal is of zero length which is considered an invalid state in this class.
|
||||
m_A = m_B = m_C = m_D = 0.0;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Constructor with plane equation coefficients
|
||||
///
|
||||
/// Define a plane by the plane equation coefficients.
|
||||
/// Setting at least the A, B and C coefficients to zero will effectually set the plane to invalid.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Plane::Plane(double A, double B, double C, double D)
|
||||
{
|
||||
m_A = A;
|
||||
m_B = B;
|
||||
m_C = C;
|
||||
m_D = D;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Copy constructor
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Plane::Plane(const Plane& other)
|
||||
: Object()
|
||||
{
|
||||
*this = other;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Destructor
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Plane::~Plane()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Assignment operator
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const Plane& Plane::operator=(const Plane& rhs)
|
||||
{
|
||||
m_A = rhs.m_A;
|
||||
m_B = rhs.m_B;
|
||||
m_C = rhs.m_C;
|
||||
m_D = rhs.m_D;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Equality operator
|
||||
///
|
||||
/// Check if the two planes are identically defined. Note, equal planes may be defined differently
|
||||
/// and are as such considered not to be identical to each other. (Different plane coefficients)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool Plane::operator==(const Plane& rhs) const
|
||||
{
|
||||
if (m_A != rhs.m_A) return false;
|
||||
if (m_B != rhs.m_B) return false;
|
||||
if (m_C != rhs.m_C) return false;
|
||||
if (m_D != rhs.m_D) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Inequality operator
|
||||
///
|
||||
/// Check if the two planes are not identically defined. Note, equal planes may be defined differently
|
||||
/// and are as such considered not to be identical to each other. (Different plane coefficients)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool Plane::operator!=(const Plane& rhs) const
|
||||
{
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Is the plane definition valid or not
|
||||
///
|
||||
/// The plane is considered invalid if the normal is of zero length
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool Plane::isValid() const
|
||||
{
|
||||
return !((m_A == 0.0) && (m_B == 0.0) && (m_C == 0.0));
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Define a plane by the plane equation coefficients
|
||||
///
|
||||
/// \param A Plane coefficient A
|
||||
/// \param B Plane coefficient B
|
||||
/// \param C Plane coefficient C
|
||||
/// \param D Plane coefficient D
|
||||
///
|
||||
/// The coefficients defines a plane by the equation: \f$Ax + By + Cz + D = 0\f$
|
||||
/// The plane coefficients \f$[A, B, C]\f$ defines the normal to the plane
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void Plane::set(double A, double B, double C, double D)
|
||||
{
|
||||
CVF_ASSERT(!(A == 0.0 && B == 0.0 && C == 0.0));
|
||||
|
||||
m_A = A;
|
||||
m_B = B;
|
||||
m_C = C;
|
||||
m_D = D;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Compute the plane equation from the given point and normal
|
||||
///
|
||||
/// \param point Point on the plane
|
||||
/// \param normal The plane's normal
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool Plane::setFromPointAndNormal(const Vec3d& point, const Vec3d& normal)
|
||||
{
|
||||
if (normal.isZero()) return false;
|
||||
|
||||
m_A = normal.x();
|
||||
m_B = normal.y();
|
||||
m_C = normal.z();
|
||||
m_D = -(normal*point);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Compute the plane equation from the given three points
|
||||
///
|
||||
/// \param p1 First point on the plane
|
||||
/// \param p2 Second point on the plane
|
||||
/// \param p3 Third point on the plane
|
||||
///
|
||||
/// \return true if successfully set. false if points are on the same line.
|
||||
///
|
||||
/// The three points must be different from each other and cannot be on the same line in space
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool Plane::setFromPoints(const Vec3d& p1, const Vec3d& p2, const Vec3d& p3)
|
||||
{
|
||||
Vec3d v1 = p2 - p1;
|
||||
Vec3d v2 = p3 - p1;
|
||||
Vec3d normal = v1 ^ v2;
|
||||
|
||||
if (normal.isZero()) return false;
|
||||
|
||||
setFromPointAndNormal(p1, normal);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the normal of the plane
|
||||
///
|
||||
/// The normal may not be normalized
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Vec3d Plane::normal() const
|
||||
{
|
||||
Vec3d normal = Vec3d(m_A, m_B, m_C);
|
||||
CVF_ASSERT(!normal.isZero());
|
||||
|
||||
return normal;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get a point located on the plane
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Vec3d Plane::pointInPlane() const
|
||||
{
|
||||
double distToOrigin = distanceToOrigin();
|
||||
Vec3d point(m_A, m_B, m_C);
|
||||
point *= distToOrigin;
|
||||
|
||||
return point;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Flip the plane
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void Plane::flip()
|
||||
{
|
||||
m_A *= -1.0;
|
||||
m_B *= -1.0;
|
||||
m_C *= -1.0;
|
||||
m_D *= -1.0;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Transforms the plane with the given homogeneous transformation \a matrix
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void Plane::transform(const Mat4d& matrix)
|
||||
{
|
||||
Vec3d n = normal();
|
||||
Vec3d point = pointInPlane();
|
||||
|
||||
n.transformVector(matrix);
|
||||
point.transformPoint(matrix);
|
||||
|
||||
setFromPointAndNormal(point, n);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the distance from the point to the plane
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double Plane::distance(const Vec3d& point) const
|
||||
{
|
||||
double factor = Math::sqrt(m_A*m_A + m_B*m_B + m_C*m_C);
|
||||
CVF_ASSERT(factor > 0.0);
|
||||
|
||||
double dist = distanceSquared(point) / factor;
|
||||
|
||||
return dist;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the square of the distance from the point to the plane
|
||||
///
|
||||
/// The square of the distance is relatively fast to compute (no \a sqrt) and is useful for determine
|
||||
/// which side the point is on. To obtain the actual distance, divide by \f$\sqrt{(A^2 + B^2 + C^2)}\f$
|
||||
/// or use the distance() function directly.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double Plane::distanceSquared(const Vec3d& point) const
|
||||
{
|
||||
return m_A*point.x() + m_B*point.y() + m_C*point.z() + m_D;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the distance from the plane to the origin
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double Plane::distanceToOrigin() const
|
||||
{
|
||||
double factor = m_A*m_A + m_B*m_B + m_C*m_C;
|
||||
CVF_ASSERT(factor > 0.0);
|
||||
|
||||
return -m_D/factor;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Project the given vector onto the plane
|
||||
///
|
||||
/// \param vector Vector to be projected
|
||||
/// \param projectedVector Projected vector to be returned by pointer
|
||||
///
|
||||
/// \return true if successfully projected.
|
||||
/// false if the given \a vector is parallel with the plane's normal
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool Plane::projectVector(const Vec3d& vector, Vec3d* projectedVector) const
|
||||
{
|
||||
CVF_ASSERT(projectedVector);
|
||||
|
||||
Vec3d n = normal();
|
||||
Vec3d tmp = n ^ vector;
|
||||
Vec3d k = tmp ^ n;
|
||||
double length = k.length();
|
||||
|
||||
if (length <= 0.0) return false;
|
||||
|
||||
k *= 1.0/length;
|
||||
length = vector*k;
|
||||
*projectedVector = k;
|
||||
*projectedVector *= length;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Project the given point onto the plane
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Vec3d Plane::projectPoint(const Vec3d& point) const
|
||||
{
|
||||
Vec3d pip = pointInPlane();
|
||||
|
||||
// Create vector from point in plane to node
|
||||
Vec3d vector = point - pip;
|
||||
|
||||
// Project vector to find node in plane
|
||||
Vec3d projectedPoint;
|
||||
if (projectVector(vector, &projectedPoint))
|
||||
{
|
||||
projectedPoint += pip;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The <point - pip> vector is parallel with the normal vector, use the point in plane as the projected
|
||||
projectedPoint = pip;
|
||||
}
|
||||
|
||||
return projectedPoint;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Find intersection line between two planes
|
||||
///
|
||||
/// \param other The other plane to find intersection line with
|
||||
/// \param point Point on line
|
||||
/// \param direction Normalized direction of line
|
||||
///
|
||||
/// \return true if success. false if direction is zero -> no point of intersection exists
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool Plane::intersect(const Plane& other, Vec3d* point, Vec3d* direction) const
|
||||
{
|
||||
// Note: Ripped from Graphics Gems III page 233.
|
||||
|
||||
CVF_ASSERT(point);
|
||||
|
||||
double invdet = UNDEFINED_DOUBLE;
|
||||
|
||||
Vec3d normal1 = this->normal();
|
||||
Vec3d normal2 = other.normal();
|
||||
Vec3d vector = normal1 ^ normal2;
|
||||
Vec3d dir2(vector.x()*vector.x(), vector.y()*vector.y(), vector.z()*vector.z());
|
||||
|
||||
// Todo: VTFIsGreater(...) and VTFeqZero(..) replacement
|
||||
if ((dir2.z() > dir2.y()) && (dir2.z() > dir2.x()) && (dir2.z() != 0.0))
|
||||
{
|
||||
// then get a point on the XY plane
|
||||
invdet = 1.0 / vector.z();
|
||||
|
||||
// solve < pl1.x() * xpt.x() + pl1.y() * xpt.y() = - pl1.w > < pl2.x() * xpt.x() + pl2.y() * xpt.y() = - pl2.w >
|
||||
point->x() = m_B*other.m_D - other.m_B*m_D;
|
||||
point->y() = other.m_A*m_D - m_A*other.m_D;
|
||||
point->z() = 0.0;
|
||||
}
|
||||
// Todo: VTFIsGreater(...) and VTFeqZero(..) replacement
|
||||
else if ((dir2.y() > dir2.x()) && (dir2.y() != 0.0))
|
||||
{
|
||||
// then get a point on the XZ plane
|
||||
invdet = 1.0f / vector.y();
|
||||
|
||||
// solve < pl1.x() * xpt.x() + pl1.z() * xpt.z() = -pl1.w > < pl2.x() * xpt.x() + pl2.z() * xpt.z() = -pl2.w >
|
||||
point->x() = other.m_C*m_D - m_C*other.m_D;
|
||||
point->y() = 0.0;
|
||||
point->z() = m_A*other.m_D - other.m_A*m_D;
|
||||
}
|
||||
// Todo: VTFeqZero(..) replacement
|
||||
else if (dir2.x() != 0.0)
|
||||
{
|
||||
// then get a point on the YZ plane
|
||||
invdet = 1.0 / vector.x();
|
||||
|
||||
// solve < pl1.y() * xpt.y() + pl1.z() * xpt.z() = - pl1.w > < pl2.y() * xpt.y() + pl2.z() * xpt.z() = - pl2.w >
|
||||
point->x() = 0.0;
|
||||
point->y() = m_C*other.m_D - other.m_C*m_D;
|
||||
point->z() = other.m_B*m_D - m_B*other.m_D;
|
||||
}
|
||||
else
|
||||
{
|
||||
// direction is zero, then no point of intersection exists
|
||||
return false;
|
||||
}
|
||||
|
||||
*point *= invdet;
|
||||
|
||||
if (direction)
|
||||
{
|
||||
*direction = vector;
|
||||
direction->normalize();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} // namespace cvf
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfObject.h"
|
||||
#include "cvfVector3.h"
|
||||
#include "cvfMatrix4.h"
|
||||
|
||||
|
||||
namespace cvf {
|
||||
|
||||
//=================================================================================================
|
||||
//
|
||||
// Plane class
|
||||
//
|
||||
//=================================================================================================
|
||||
class Plane : public Object
|
||||
{
|
||||
public:
|
||||
Plane();
|
||||
Plane(double A, double B, double C, double D);
|
||||
Plane(const Plane& other);
|
||||
~Plane();
|
||||
|
||||
const Plane& operator=(const Plane& other);
|
||||
bool operator==(const Plane& other) const;
|
||||
bool operator!=(const Plane& other) const;
|
||||
|
||||
inline double A() const { return m_A; } ///< Get plane coefficient A
|
||||
inline double B() const { return m_B; } ///< Get plane coefficient B
|
||||
inline double C() const { return m_C; } ///< Get plane coefficient C
|
||||
inline double D() const { return m_D; } ///< Get plane coefficient D
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
void set(double A, double B, double C, double D);
|
||||
bool setFromPointAndNormal(const Vec3d& point, const Vec3d& normal);
|
||||
bool setFromPoints(const Vec3d& p1, const Vec3d& p2, const Vec3d& p3);
|
||||
|
||||
Vec3d normal() const;
|
||||
Vec3d pointInPlane() const;
|
||||
|
||||
void flip();
|
||||
void transform(const Mat4d& matrix);
|
||||
|
||||
double distance(const Vec3d& point) const;
|
||||
double distanceSquared(const Vec3d& point) const;
|
||||
double distanceToOrigin() const;
|
||||
|
||||
bool projectVector(const Vec3d& vector, Vec3d* projectedVector) const;
|
||||
Vec3d projectPoint(const Vec3d& point) const;
|
||||
|
||||
bool intersect(const Plane& other, Vec3d* point, Vec3d* direction = NULL) const;
|
||||
|
||||
private:
|
||||
double m_A; // Plane equation coefficients
|
||||
double m_B; //
|
||||
double m_C; //
|
||||
double m_D; //
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfVector3.h"
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// This class implements a quaternion
|
||||
//
|
||||
//==================================================================================================
|
||||
template<typename S>
|
||||
class Quat
|
||||
{
|
||||
public:
|
||||
Quat();
|
||||
Quat(S x, S y, S z, S w);
|
||||
Quat(const Quat& other);
|
||||
|
||||
template<typename T>
|
||||
explicit Quat(const T& other);
|
||||
|
||||
Quat& operator=(const Quat& rhs);
|
||||
bool operator==(const Quat& rhs) const;
|
||||
bool operator!=(const Quat& rhs) const;
|
||||
|
||||
const S& x() const { return m_x; } ///< Get the X element of the quaternion
|
||||
const S& y() const { return m_y; } ///< Get the Y element of the quaternion
|
||||
const S& z() const { return m_z; } ///< Get the Z element of the quaternion
|
||||
const S& w() const { return m_w; } ///< Get the W element of the quaternion
|
||||
S& x() { return m_x; } ///< Get a reference to the X element of the quaternion. E.g. x() = 2;
|
||||
S& y() { return m_y; } ///< Get a reference to the Y element of the quaternion. E.g. y() = 2;
|
||||
S& z() { return m_z; } ///< Get a reference to the Z element of the quaternion. E.g. z() = 2;
|
||||
S& w() { return m_w; } ///< Get a reference to the W element of the quaternion. E.g. w() = 2;
|
||||
|
||||
void set(S x, S y, S z, S w);
|
||||
|
||||
bool normalize();
|
||||
|
||||
// The setFromAxisAngle() function is left as a placeholder to illustrate naming of functions
|
||||
void setFromAxisAngle(Vector3<S> rotationAxis, S angle);
|
||||
void toAxisAngle(Vector3<S>* rotationAxis, S* angle) const;
|
||||
|
||||
Matrix3<S> toMatrix3() const;
|
||||
Matrix4<S> toMatrix4() const;
|
||||
|
||||
static Quat fromAxisAngle(Vector3<S> rotationAxis, S angle);
|
||||
static Quat fromRotationMatrix(const Matrix4<S>& rotMat);
|
||||
|
||||
private:
|
||||
S m_x;
|
||||
S m_y;
|
||||
S m_z;
|
||||
S m_w;
|
||||
};
|
||||
|
||||
typedef Quat<float> Quatf;
|
||||
typedef Quat<double> Quatd;
|
||||
|
||||
}
|
||||
|
||||
#include "cvfQuat.inl"
|
||||
@@ -0,0 +1,376 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::Quat
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// Templated quaternion
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Default constructor, initializes all elements to 0
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
Quat<S>::Quat()
|
||||
: m_x(0),
|
||||
m_y(0),
|
||||
m_z(0),
|
||||
m_w(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Constructor with initialization
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
Quat<S>::Quat(S x, S y, S z, S w)
|
||||
: m_x(x),
|
||||
m_y(y),
|
||||
m_z(z),
|
||||
m_w(w)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Copy constructor
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
Quat<S>::Quat(const Quat& other)
|
||||
: m_x(other.m_x),
|
||||
m_y(other.m_y),
|
||||
m_z(other.m_z),
|
||||
m_w(other.m_w)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Conversion constructor for explicit conversion
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
template<typename T>
|
||||
Quat<S>::Quat(const T& other)
|
||||
{
|
||||
m_x = static_cast<S>(other.x());
|
||||
m_y = static_cast<S>(other.y());
|
||||
m_z = static_cast<S>(other.z());
|
||||
m_w = static_cast<S>(other.w());
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Assignment operator
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
Quat<S>& Quat<S>::operator=(const Quat& rhs)
|
||||
{
|
||||
m_x = rhs.m_x;
|
||||
m_y = rhs.m_y;
|
||||
m_z = rhs.m_z;
|
||||
m_w = rhs.m_w;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
bool Quat<S>::operator==(const Quat& rhs) const
|
||||
{
|
||||
if (m_x != rhs.m_x) return false;
|
||||
if (m_y != rhs.m_y) return false;
|
||||
if (m_z != rhs.m_z) return false;
|
||||
if (m_w != rhs.m_w) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
bool Quat<S>::operator!=(const Quat& rhs) const
|
||||
{
|
||||
if (m_x != rhs.m_x) return true;
|
||||
if (m_y != rhs.m_y) return true;
|
||||
if (m_z != rhs.m_z) return true;
|
||||
if (m_w != rhs.m_w) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
void Quat<S>::set(S x, S y, S z, S w)
|
||||
{
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
m_z = z;
|
||||
m_w = w;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Normalize the quaternion
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
bool Quat<S>::normalize()
|
||||
{
|
||||
// Quaternions always obey: a^2 + b^2 + c^2 + d^2 = 1.0.
|
||||
// If they don't add up to 1.0, dividing by their magnitude will re-normalize them.
|
||||
|
||||
S len = Math::sqrt(m_x*m_x + m_y*m_y + m_z*m_z + m_w*m_w);
|
||||
|
||||
if (len > 0)
|
||||
{
|
||||
// Pre-compute 1/length and do multiplication instead of division
|
||||
S oneOverLen = static_cast<S>(1.0/len);
|
||||
m_x *= oneOverLen;
|
||||
m_y *= oneOverLen;
|
||||
m_z *= oneOverLen;
|
||||
m_w *= oneOverLen;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Might be NaN, so set it to zero
|
||||
m_x = 0;
|
||||
m_y = 0;
|
||||
m_z = 0;
|
||||
m_w = 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Sets the quaternion from a rotation axis and an angle (in radians)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
void Quat<S>::setFromAxisAngle(Vector3<S> rotationAxis, S angle)
|
||||
{
|
||||
*this = Quat::fromAxisAngle(rotationAxis, angle);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Extracts the rotation in this quaternion as an axis and an angle (in radians)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
void Quat<S>::toAxisAngle(Vector3<S>* rotationAxis, S* angle) const
|
||||
{
|
||||
// From matrix an quaternion FAQ
|
||||
|
||||
CVF_ASSERT(rotationAxis);
|
||||
CVF_ASSERT(angle);
|
||||
|
||||
// Need a normalized quaternion
|
||||
Quat nQ(*this);
|
||||
nQ.normalize();
|
||||
|
||||
S cos_a = nQ.m_w;
|
||||
*angle = 2*Math::acos(cos_a);
|
||||
|
||||
S sin_a = Math::sqrt(1 - cos_a*cos_a);
|
||||
if (Math::abs(sin_a) < 0.0005) sin_a = 1;
|
||||
|
||||
rotationAxis->x() = nQ.m_x/sin_a;
|
||||
rotationAxis->y() = nQ.m_y/sin_a;
|
||||
rotationAxis->z() = nQ.m_z/sin_a;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Constructs a rotation matrix from this quaternion
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
Matrix3<S> Quat<S>::toMatrix3() const
|
||||
{
|
||||
// Based on Quaternions paper by Ken Shoemake
|
||||
// The current version works even if quaternion isn't normalized
|
||||
// If we assume that the quaternion is normalized, this function can be made simpler/quicker
|
||||
|
||||
S Nq = m_x*m_x + m_y*m_y + m_z*m_z + m_w*m_w;
|
||||
S s = (Nq > 0) ? (2/Nq) : 0;
|
||||
|
||||
S xs = m_x*s;
|
||||
S ys = m_y*s;
|
||||
S zs = m_z*s;
|
||||
|
||||
S wx = m_w*xs;
|
||||
S wy = m_w*ys;
|
||||
S wz = m_w*zs;
|
||||
S xx = m_x*xs;
|
||||
S xy = m_x*ys;
|
||||
S xz = m_x*zs;
|
||||
S yy = m_y*ys;
|
||||
S yz = m_y*zs;
|
||||
S zz = m_z*zs;
|
||||
|
||||
|
||||
// Default constructor initializes to identity
|
||||
Matrix3<S> m;
|
||||
m.setRowCol( 0, 0, 1 - (yy + zz));
|
||||
m.setRowCol( 0, 1, xy - wz );
|
||||
m.setRowCol( 0, 2, xz + wy );
|
||||
|
||||
m.setRowCol( 1, 0, xy + wz );
|
||||
m.setRowCol( 1, 1, 1 - (xx + zz));
|
||||
m.setRowCol( 1, 2, yz - wx );
|
||||
|
||||
m.setRowCol( 2, 0, xz - wy );
|
||||
m.setRowCol( 2, 1, yz + wx );
|
||||
m.setRowCol( 2, 2, 1 - (xx + yy));
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Constructs a rotation matrix from this quaternion
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
Matrix4<S> Quat<S>::toMatrix4() const
|
||||
{
|
||||
// Create via the Matrix3 version
|
||||
return Matrix4<S>(toMatrix3());
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Creates a quaternion from specified rotation axis and angle (in radians)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
Quat<S> Quat<S>::fromAxisAngle(Vector3<S> rotationAxis, S angle)
|
||||
{
|
||||
// From matrix an quaternion FAQ
|
||||
|
||||
rotationAxis.normalize();
|
||||
|
||||
S halfAngle = static_cast<S>(angle/2.0);
|
||||
S sinHalfAngle = Math::sin(halfAngle);
|
||||
|
||||
Quat q;
|
||||
q.m_x = rotationAxis.x()*sinHalfAngle;;
|
||||
q.m_y = rotationAxis.y()*sinHalfAngle;
|
||||
q.m_z = rotationAxis.z()*sinHalfAngle;
|
||||
q.m_w = Math::cos(halfAngle);
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Creates a quaternion from the passed rotation matrix
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
Quat<S> Quat<S>::fromRotationMatrix(const Matrix4<S>& rotMat)
|
||||
{
|
||||
const S m00 = rotMat.rowCol(0, 0);
|
||||
const S m01 = rotMat.rowCol(0, 1);
|
||||
const S m02 = rotMat.rowCol(0, 2);
|
||||
const S m10 = rotMat.rowCol(1, 0);
|
||||
const S m11 = rotMat.rowCol(1, 1);
|
||||
const S m12 = rotMat.rowCol(1, 2);
|
||||
const S m20 = rotMat.rowCol(2, 0);
|
||||
const S m21 = rotMat.rowCol(2, 1);
|
||||
const S m22 = rotMat.rowCol(2, 2);
|
||||
|
||||
|
||||
// If the trace of the matrix is greater than zero, then perform an "instant" calculation.
|
||||
S trace = m00 + m11 + m22;
|
||||
|
||||
Quat q(0, 0, 0, 1);
|
||||
|
||||
// Try and test against a very small value instead of 0 here
|
||||
// The FAQ suggests testing against ( T > 0.00000001 ) to avoid large distortions
|
||||
if (trace > 0.00000001)
|
||||
{
|
||||
S s = Math::sqrt(trace + 1)*2;
|
||||
|
||||
q.m_x = (m21 - m12)/s;
|
||||
q.m_y = (m02 - m20)/s;
|
||||
q.m_z = (m10 - m01)/s;
|
||||
q.m_w = static_cast<S>(0.25*s);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the trace of the matrix is equal to zero then identify
|
||||
// which major diagonal element has the greatest value.
|
||||
int iDominantColumn = 0;
|
||||
if (m11 > m00) iDominantColumn = 1;
|
||||
if (m22 > m11) iDominantColumn = 2;
|
||||
|
||||
if (iDominantColumn == 0)
|
||||
{
|
||||
S s = Math::sqrt(1 + m00 - m11 - m22)*2;
|
||||
if (s > 0)
|
||||
{
|
||||
q.m_x = static_cast<S>(0.25*s);
|
||||
q.m_y = (m10 + m01)/s;
|
||||
q.m_z = (m20 + m02)/s;
|
||||
q.m_w = (m21 - m12)/s;
|
||||
}
|
||||
}
|
||||
else if (iDominantColumn == 1)
|
||||
{
|
||||
S s = Math::sqrt(1 + m11 - m00 - m22)*2;
|
||||
if (s > 0)
|
||||
{
|
||||
q.m_x = (m10 + m01)/s;
|
||||
q.m_y = static_cast<S>(0.25*s);
|
||||
q.m_z = (m21 + m12)/s;
|
||||
q.m_w = (m02 - m20)/s;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
S s = Math::sqrt(1 + m22 - m00 - m11)*2;
|
||||
if (s > 0)
|
||||
{
|
||||
q.m_x = (m20 + m02)/s;
|
||||
q.m_y = (m21 + m12)/s;
|
||||
q.m_z = static_cast<S>(0.25*s);
|
||||
q.m_w = (m10 - m01)/s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
} // namespace cvf
|
||||
@@ -0,0 +1,84 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
#include "cvfVector2.h"
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
template <typename T>
|
||||
class Rect
|
||||
{
|
||||
public:
|
||||
Rect();
|
||||
Rect(T minX, T minY, T width, T height);
|
||||
Rect(const Vector2<T>& min, T width, T height);
|
||||
Rect(const Rect& rect);
|
||||
|
||||
Rect& operator=(const Rect& rhs);
|
||||
|
||||
Vector2<T> min() const;
|
||||
Vector2<T> max() const;
|
||||
T width() const;
|
||||
T height() const;
|
||||
Vector2<T> center() const;
|
||||
|
||||
void setMin(const Vector2<T>& min);
|
||||
void setWidth(T width);
|
||||
void setHeight(T height);
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
void include(const Vector2<T>& coord);
|
||||
void include(const Rect& rect);
|
||||
|
||||
bool contains(const Vector2<T>& coord) const;
|
||||
bool intersects(const Rect& rect) const;
|
||||
|
||||
void normalize();
|
||||
|
||||
void translate(const Vector2<T>& offset);
|
||||
|
||||
bool segmentIntersect(const Vec2d& p1, const Vec2d& p2, Vec2d* intersect1, Vec2d* intersect2);
|
||||
|
||||
static Rect fromMinMax(const Vector2<T>& min, const Vector2<T>& max);
|
||||
|
||||
private:
|
||||
static bool clipTest(double p, double q, double *u1, double *u2);
|
||||
|
||||
private:
|
||||
Vector2<T> m_minPos; ///< Position of left lower corner
|
||||
T m_width; ///< Width
|
||||
T m_height; ///< Height
|
||||
};
|
||||
|
||||
typedef Rect<float> Rectf; ///< A rect with float components
|
||||
typedef Rect<double> Rectd; ///< A rect with double components
|
||||
typedef Rect<int> Recti; ///< A rect with integer components
|
||||
typedef Rect<uint> Rectui; ///< A rect with unsigned integer components
|
||||
|
||||
}
|
||||
|
||||
#include "cvfRect.inl"
|
||||
@@ -0,0 +1,575 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::Rect
|
||||
/// \ingroup Core
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
Rect<T>::Rect()
|
||||
{
|
||||
m_minPos.setZero();
|
||||
m_width = 0;
|
||||
m_height = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
Rect<T>::Rect(T minX, T minY, T width, T height)
|
||||
{
|
||||
m_minPos.set(minX, minY);
|
||||
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
Rect<T>::Rect(const Vector2<T>& min, T width, T height)
|
||||
{
|
||||
m_minPos = min;
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
Rect<T>::Rect(const Rect& rect)
|
||||
{
|
||||
m_minPos = rect.min();
|
||||
m_width = rect.width();
|
||||
m_height = rect.height();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Assignment operator
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
Rect<T>& Rect<T>::operator=(const Rect& rhs)
|
||||
{
|
||||
m_minPos = rhs.min();
|
||||
m_width = rhs.max().x() - rhs.min().x();
|
||||
m_height = rhs.max().y() - rhs.min().y();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
Vector2<T> Rect<T>::min() const
|
||||
{
|
||||
return m_minPos;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
Vector2<T> Rect<T>::max() const
|
||||
{
|
||||
Vector2<T> max(m_minPos);
|
||||
max.x() += m_width;
|
||||
max.y() += m_height;
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
T Rect<T>::width() const
|
||||
{
|
||||
return m_width;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
T Rect<T>::height() const
|
||||
{
|
||||
return m_height;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
Vector2<T> Rect<T>::center() const
|
||||
{
|
||||
Vector2<T> center(m_minPos);
|
||||
center.x() += m_width / 2.0;
|
||||
center.y() += m_height / 2.0;
|
||||
|
||||
return center;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void Rect<T>::setMin(const Vector2<T>& min)
|
||||
{
|
||||
m_minPos = min;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void Rect<T>::setWidth(T width)
|
||||
{
|
||||
m_width = width;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void Rect<T>::setHeight(T height)
|
||||
{
|
||||
m_height = height;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
bool Rect<T>::isValid() const
|
||||
{
|
||||
return m_width > 0.0 && m_height > 0.0;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void Rect<T>::include(const Vector2<T>& coord)
|
||||
{
|
||||
if (!isValid())
|
||||
{
|
||||
Vector2<T> diff = coord - m_minPos;
|
||||
m_width = diff.x();
|
||||
m_height = diff.y();
|
||||
return;
|
||||
}
|
||||
|
||||
if (coord.x() < m_minPos.x())
|
||||
{
|
||||
T deltaX = m_minPos.x() - coord.x();
|
||||
m_minPos.x() -= deltaX;
|
||||
m_width += deltaX;
|
||||
}
|
||||
else if (coord.x() > m_minPos.x() + m_width)
|
||||
{
|
||||
T deltaX = coord.x() - (m_minPos.x() + m_width);
|
||||
m_width += deltaX;
|
||||
}
|
||||
|
||||
if (coord.y() < m_minPos.y())
|
||||
{
|
||||
T deltaY = m_minPos.y() - coord.y();
|
||||
m_minPos.y() -= deltaY;
|
||||
m_height += deltaY;
|
||||
}
|
||||
else if (coord.y() > m_minPos.y() + m_height)
|
||||
{
|
||||
T deltaY = coord.y() - (m_minPos.y() + m_height);
|
||||
m_height += deltaY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void Rect<T>::include(const Rect& rect)
|
||||
{
|
||||
if (!rect.isValid()) return;
|
||||
|
||||
T left = m_minPos.x();
|
||||
T right = m_minPos.x();
|
||||
if (m_width < 0)
|
||||
left += m_width;
|
||||
else
|
||||
right += m_width;
|
||||
|
||||
if (rect.width() < 0)
|
||||
{
|
||||
left = CVF_MIN(left, rect.min().x() + rect.width());
|
||||
right = CVF_MAX(right, rect.min().x());
|
||||
}
|
||||
else
|
||||
{
|
||||
left = CVF_MIN(left, rect.min().x());
|
||||
right = CVF_MAX(right, rect.min().x() + rect.width());
|
||||
}
|
||||
|
||||
T bottom = m_minPos.y();
|
||||
T top = m_minPos.y();
|
||||
if (m_height < 0)
|
||||
{
|
||||
bottom += m_height;
|
||||
}
|
||||
else
|
||||
{
|
||||
top += m_height;
|
||||
}
|
||||
|
||||
if (rect.height() < 0)
|
||||
{
|
||||
bottom = CVF_MIN(bottom, rect.min().y() + rect.height());
|
||||
top = CVF_MAX(top, rect.min().y());
|
||||
}
|
||||
else
|
||||
{
|
||||
bottom = CVF_MIN(bottom, rect.min().y());
|
||||
top = CVF_MAX(top, rect.min().y() + rect.height());
|
||||
}
|
||||
|
||||
m_minPos.set(left, bottom);
|
||||
m_width = right - left;
|
||||
m_height = top - bottom;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
bool Rect<T>::contains(const Vector2<T>& coord) const
|
||||
{
|
||||
T left = m_minPos.x();
|
||||
T right = m_minPos.x();
|
||||
if (m_width < 0)
|
||||
{
|
||||
left += m_width;
|
||||
}
|
||||
else
|
||||
{
|
||||
right += m_width;
|
||||
}
|
||||
|
||||
if (left == right)
|
||||
{
|
||||
// null rect
|
||||
return false;
|
||||
}
|
||||
|
||||
if (coord.x() < left || coord.x() > right)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
T bot = m_minPos.y();
|
||||
T top = m_minPos.y();
|
||||
if (m_height < 0)
|
||||
{
|
||||
bot += m_height;
|
||||
}
|
||||
else
|
||||
{
|
||||
top += m_height;
|
||||
}
|
||||
|
||||
if (bot == top)
|
||||
{
|
||||
// null rect
|
||||
return false;
|
||||
}
|
||||
|
||||
if (coord.y() < bot || coord.y() > top)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
bool Rect<T>::intersects(const Rect& rect) const
|
||||
{
|
||||
T left1 = m_minPos.x();
|
||||
T right1 = m_minPos.x();
|
||||
if (m_width < 0)
|
||||
{
|
||||
left1 += m_width;
|
||||
}
|
||||
else
|
||||
{
|
||||
right1 += m_width;
|
||||
}
|
||||
|
||||
if (left1 == right1)
|
||||
{
|
||||
// null rect
|
||||
return false;
|
||||
}
|
||||
|
||||
T left2 = rect.min().x();
|
||||
T right2 = rect.min().x();
|
||||
if (rect.width() < 0)
|
||||
{
|
||||
left2 += rect.width();
|
||||
}
|
||||
else
|
||||
{
|
||||
right2 += rect.width();
|
||||
}
|
||||
|
||||
if (left2 == right2)
|
||||
{
|
||||
// null rect
|
||||
return false;
|
||||
}
|
||||
|
||||
if (left1 >= right2 || left2 >= right1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
T bot1 = m_minPos.y();
|
||||
T top1 = m_minPos.y();
|
||||
if (m_height < 0)
|
||||
{
|
||||
bot1 += m_height;
|
||||
}
|
||||
else
|
||||
{
|
||||
top1 += m_height;
|
||||
}
|
||||
|
||||
if (bot1 == top1)
|
||||
{
|
||||
// null rect
|
||||
return false;
|
||||
}
|
||||
|
||||
T bot2 = rect.min().y();
|
||||
T top2 = rect.min().y();
|
||||
if (rect.height() < 0)
|
||||
{
|
||||
bot2 += rect.height();
|
||||
}
|
||||
else
|
||||
{
|
||||
top2 += rect.height();
|
||||
}
|
||||
|
||||
if (bot2 == top2)
|
||||
{
|
||||
// null rect
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bot1 >= top2 || bot2 >= top1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void Rect<T>::normalize()
|
||||
{
|
||||
if (m_width < 0)
|
||||
{
|
||||
m_width = -m_width;
|
||||
m_minPos.x() -= m_width;
|
||||
}
|
||||
|
||||
if (m_height < 0)
|
||||
{
|
||||
m_height = -m_height;
|
||||
m_minPos.y() -= m_height;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void Rect<T>::translate(const Vector2<T>& offset)
|
||||
{
|
||||
m_minPos += offset;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
Rect<T> Rect<T>::fromMinMax(const Vector2<T>& min, const Vector2<T>& max)
|
||||
{
|
||||
Rect<T> rect(min, max.x() - min.x(), max.y() - min.y());
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
bool Rect<T>::segmentIntersect(const Vec2d& p1, const Vec2d& p2, Vec2d* intersect1, Vec2d* intersect2)
|
||||
{
|
||||
// Uses Liang-Barsky line clipping algorithm
|
||||
// See http://stackoverflow.com/questions/99353/how-to-test-if-a-line-segment-intersects-an-axis-aligned-rectange-in-2d
|
||||
CVF_ASSERT(intersect1);
|
||||
CVF_ASSERT(intersect2);
|
||||
|
||||
if (!isValid()) return false;
|
||||
|
||||
double u1 = 0.0;
|
||||
double u2 = 1.0;
|
||||
double dx = p2.x() - p1.x();
|
||||
double dy;
|
||||
|
||||
Vec2d maxPos = max();
|
||||
|
||||
if (clipTest(-dx, p1.x() - m_minPos.x(), &u1, &u2))
|
||||
{
|
||||
if (clipTest(dx, maxPos.x() - p1.x(), &u1, &u2))
|
||||
{
|
||||
dy = p2.y() - p1.y();
|
||||
if (clipTest (-dy, p1.y() - m_minPos.y(), &u1, &u2))
|
||||
{
|
||||
if (clipTest (dy, maxPos.y() - p1.y(), &u1, &u2))
|
||||
{
|
||||
*intersect1 = p1;
|
||||
*intersect2 = p2;
|
||||
if (u2 < 1.0)
|
||||
{
|
||||
intersect2->x() = p1.x() + u2 * dx;
|
||||
intersect2->y() = p1.y() + u2 * dy;
|
||||
}
|
||||
if (u1 > 0.0)
|
||||
{
|
||||
intersect1->x() += u1 * dx;
|
||||
intersect1->y() += u1 * dy;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
bool Rect<T>::clipTest(double p, double q, double *u1, double *u2)
|
||||
{
|
||||
// Uses Liang-Barsky line clipping algorithm
|
||||
// See also http://stackoverflow.com/questions/99353/how-to-test-if-a-line-segment-intersects-an-axis-aligned-rectange-in-2d
|
||||
CVF_ASSERT(u1);
|
||||
CVF_ASSERT(u2);
|
||||
|
||||
bool retval = true;
|
||||
|
||||
if (p < 0.0)
|
||||
{
|
||||
double r = q / p;
|
||||
if (r > *u2)
|
||||
{
|
||||
retval = false;
|
||||
}
|
||||
else if (r > *u1)
|
||||
{
|
||||
*u1 = r;
|
||||
}
|
||||
}
|
||||
else if (p > 0.0)
|
||||
{
|
||||
double r = q / p;
|
||||
if (r < *u1)
|
||||
{
|
||||
retval = false;
|
||||
}
|
||||
else if (r < *u2)
|
||||
{
|
||||
*u2 = r;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// p = 0, so line is parallel to this clipping edge
|
||||
if(q < 0.0)
|
||||
{
|
||||
// Line is outside clipping edge
|
||||
retval = false;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
} // namespace cvf
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,118 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfCharArray.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// A general unicode based string class
|
||||
//
|
||||
//==================================================================================================
|
||||
class String
|
||||
{
|
||||
public:
|
||||
String();
|
||||
String(const std::string& str);
|
||||
String(const std::wstring& str);
|
||||
String(const String& str);
|
||||
String(const char* str);
|
||||
String(const wchar_t* str);
|
||||
|
||||
explicit String(char c);
|
||||
|
||||
explicit String(int number);
|
||||
explicit String(int64 number);
|
||||
explicit String(uint number);
|
||||
explicit String(float number);
|
||||
explicit String(double number);
|
||||
|
||||
String& operator=(String rhs);
|
||||
bool operator==(const String& rhs) const;
|
||||
bool operator==(const wchar_t* rhs) const;
|
||||
bool operator<(const String& rhs) const;
|
||||
bool operator!=(const String& rhs) const;
|
||||
const String operator+(const String& rhs) const;
|
||||
String& operator+=(const String& rhs);
|
||||
|
||||
const wchar_t& operator[](size_t pos) const;
|
||||
wchar_t& operator[](size_t pos);
|
||||
|
||||
String toLower() const;
|
||||
String toUpper() const;
|
||||
String trimmedRight() const;
|
||||
String trimmedLeft() const;
|
||||
String trimmed() const;
|
||||
String simplified() const;
|
||||
|
||||
std::vector<String> split(const String& delimiters = " ") const;
|
||||
size_t find(const String& str, size_t start = 0) const;
|
||||
String subString(size_t start, size_t length = npos) const;
|
||||
void replace(const String& before, const String& after);
|
||||
|
||||
CharArray toAscii() const; // Useful when you need a const char* pointer.
|
||||
std::string toStdString() const;
|
||||
std::wstring toStdWString() const;
|
||||
|
||||
CharArray toUtf8() const;
|
||||
static String fromUtf8(const char* str);
|
||||
|
||||
bool isEmpty() const;
|
||||
size_t size() const;
|
||||
void resize(size_t size);
|
||||
|
||||
const wchar_t* ptr() const;
|
||||
wchar_t* ptr();
|
||||
|
||||
static String number(float n, char format = 'g', int precision = -1);
|
||||
static String number(double n, char format = 'g', int precision = -1);
|
||||
|
||||
double toDouble(bool* ok = NULL) const;
|
||||
double toDouble(double defaultValue) const;
|
||||
float toFloat(bool* ok = NULL) const;
|
||||
float toFloat(float defaultValue) const;
|
||||
int toInt(bool* ok = NULL) const;
|
||||
int toInt(int defaultValue) const;
|
||||
|
||||
String arg(const String& a, int fieldWidth = 0, const wchar_t& fillChar = ' ') const;
|
||||
String arg(char a, int fieldWidth = 0, const wchar_t& fillChar = ' ') const;
|
||||
|
||||
String arg(int a, int fieldWidth = 0, const wchar_t& fillChar = ' ') const;
|
||||
String arg(int64 a, int fieldWidth = 0, const wchar_t& fillChar = ' ') const;
|
||||
String arg(uint a, int fieldWidth = 0, const wchar_t& fillChar = ' ') const;
|
||||
String arg(float a, int fieldWidth = 0, char format = 'g', int precision = -1, const wchar_t& fillChar = ' ') const;
|
||||
String arg(double a, int fieldWidth = 0, char format = 'g', int precision = -1, const wchar_t& fillChar = ' ') const;
|
||||
|
||||
void swap(String& other);
|
||||
|
||||
static const size_t npos; // Same as std::string::npos. This value, when used as the value for a count parameter n in string's member functions, roughly indicates "as many as possible".
|
||||
// As a return value it is usually used to indicate failure.
|
||||
private:
|
||||
std::wstring m_string;
|
||||
};
|
||||
|
||||
String operator+(const char* str1, const String& str2);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,313 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfSystem.h"
|
||||
#include "cvfString.h"
|
||||
|
||||
#include <memory>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::System
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// Static wrapper class for system functions
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Check if we're running 64bit
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool System::is64Bit()
|
||||
{
|
||||
return (sizeof(void*) == 8) ? true : false;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Check if we are running on a big endian system.
|
||||
///
|
||||
/// \return Returns true if we're on big endian, false for little endian.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool System::isBigEndian()
|
||||
{
|
||||
int iInt = 1;
|
||||
char* pcChar = reinterpret_cast<char*>(&iInt);
|
||||
|
||||
return !(*pcChar);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool System::memcpy(void* dst, size_t dstSizeInBytes, const void* src, size_t numBytesToCopy)
|
||||
{
|
||||
#if WIN32
|
||||
|
||||
// Debug version asserts
|
||||
errno_t err = memcpy_s(dst, dstSizeInBytes, src, numBytesToCopy);
|
||||
if (err == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
if (!dst || dstSizeInBytes == 0 || !src)
|
||||
{
|
||||
// Be consistent with the behavior of memcpy_s.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (numBytesToCopy > dstSizeInBytes)
|
||||
{
|
||||
// The source memory is too large to copy to the destination.
|
||||
// To be consistent with memcpy_s, return false to indicate failure
|
||||
return false;
|
||||
}
|
||||
|
||||
::memcpy(dst, src, numBytesToCopy);
|
||||
|
||||
return true;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool System::strcpy(char* strDestination, size_t maxNumElementsInDestination, const char* strSource)
|
||||
{
|
||||
#ifdef WIN32
|
||||
|
||||
// Debug version asserts
|
||||
// Note that on windows the debug versions functions first fills the buffer with 0xFD
|
||||
errno_t err = strcpy_s(strDestination, maxNumElementsInDestination, strSource);
|
||||
if (err == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
CVF_UNUSED(maxNumElementsInDestination);
|
||||
::strcpy(strDestination, strSource);
|
||||
|
||||
return true;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Append a string
|
||||
///
|
||||
/// \param strDestination Null-terminated destination string buffer
|
||||
/// \param maxNumElementsInDestination Total size of the destination string buffer in characters
|
||||
/// \param strSource Null-terminated source string buffer
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool System::strcat(char* strDestination, size_t maxNumElementsInDestination, const char* strSource)
|
||||
{
|
||||
#ifdef WIN32
|
||||
|
||||
errno_t err = strcat_s(strDestination, maxNumElementsInDestination, strSource);
|
||||
if (err == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
if (!strDestination || maxNumElementsInDestination == 0 || !strSource)
|
||||
{
|
||||
// Be consistent with the behavior of strcat_s.
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t dstLen = strlen(strDestination);
|
||||
size_t srcLen = strlen(strSource);
|
||||
size_t sumLen = srcLen + dstLen;
|
||||
if (sumLen + 1 > maxNumElementsInDestination)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
strncat(strDestination, strSource, srcLen);
|
||||
strDestination[sumLen] = 0;
|
||||
|
||||
return true;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Wrapper for sprintf
|
||||
///
|
||||
/// \param buffer The buffer to write into
|
||||
/// \param maxNumElementsInBuffer Size of the buffer in number of characters
|
||||
/// \param format Format string
|
||||
///
|
||||
/// \return Number of character written into buffer, excluding the terminating NULL character.
|
||||
/// If the function fails the return is -1
|
||||
///
|
||||
/// Not that at most maxNumElementsInBuffer - 1 characters are ever written into the buffer since
|
||||
/// a termination character is always written to the last position in the buffer.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int System::sprintf(char* buffer, size_t maxNumElementsInBuffer, const char* format, ...)
|
||||
{
|
||||
if (!buffer || maxNumElementsInBuffer == 0 || !format)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
va_list argList;
|
||||
va_start(argList, format);
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
int numWritten = vsnprintf_s(buffer, maxNumElementsInBuffer*sizeof(char), maxNumElementsInBuffer - 1, format, argList);
|
||||
|
||||
#else
|
||||
|
||||
int numWritten = vsnprintf(buffer, maxNumElementsInBuffer, format, argList);
|
||||
|
||||
// Linux will fill the buffer without adding a NULL
|
||||
// Catch this and report as error
|
||||
if (numWritten == static_cast<int>(maxNumElementsInBuffer))
|
||||
{
|
||||
numWritten = -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
va_end(argList);
|
||||
|
||||
// Ensure buffer is NULL terminated
|
||||
buffer[maxNumElementsInBuffer - 1] = '\0';
|
||||
|
||||
return numWritten;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Wrapper for sprintf
|
||||
///
|
||||
/// \param buffer The buffer to write into
|
||||
/// \param maxNumElementsInBuffer Size of the buffer in number of wide characters (not bytes)
|
||||
/// \param format Format string
|
||||
///
|
||||
/// \return Number of wide character written into buffer, excluding the terminating NULL character.
|
||||
/// If the function fails the return is -1
|
||||
///
|
||||
/// Not that at most maxNumElementsInBuffer - 1 characters are ever written into the buffer since
|
||||
/// a termination character is always written to the last position in the buffer.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int System::swprintf(wchar_t* buffer, size_t maxNumElementsInBuffer, const wchar_t* format, ...)
|
||||
{
|
||||
if (!buffer || maxNumElementsInBuffer == 0 || !format)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
va_list argList;
|
||||
va_start(argList, format);
|
||||
|
||||
#ifdef WIN32
|
||||
int numWritten = _vsnwprintf_s(buffer, maxNumElementsInBuffer, maxNumElementsInBuffer - 1, format, argList);
|
||||
#else
|
||||
int numWritten = vswprintf(buffer, maxNumElementsInBuffer, format, argList);
|
||||
#endif
|
||||
|
||||
va_end(argList);
|
||||
|
||||
buffer[maxNumElementsInBuffer - 1] = L'\0';
|
||||
|
||||
return numWritten;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t System::strlen(const char* str)
|
||||
{
|
||||
if (str)
|
||||
{
|
||||
return ::strlen(str);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int System::strcmp(const char* str1, const char* str2)
|
||||
{
|
||||
if (str1 == NULL || str2 == NULL)
|
||||
{
|
||||
if (str1 == NULL && str2 == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (str1 == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return ::strcmp(str1, str2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace cvf
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Static wrapper class for system functions
|
||||
//
|
||||
//==================================================================================================
|
||||
class System
|
||||
{
|
||||
public:
|
||||
static bool is64Bit();
|
||||
static bool isBigEndian();
|
||||
|
||||
static bool memcpy(void* dst, size_t dstSizeInBytes, const void* src, size_t numBytesToCopy);
|
||||
static bool strcpy(char* strDestination, size_t maxNumElementsInDestination, const char* strSource);
|
||||
static bool strcat(char* strDestination, size_t maxNumElementsInDestination, const char* strSource);
|
||||
static int sprintf(char* buffer, size_t maxNumElementsInBuffer, const char* format, ...);
|
||||
static int swprintf(wchar_t* buffer, size_t maxNumElementsInBuffer, const wchar_t* format, ...);
|
||||
static size_t strlen(const char* str);
|
||||
static int strcmp(const char* str1, const char* str2);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfTBBControl.h"
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::TBBControl
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// Static class used to enable or disable the use of Intel TBB inside the libraries.
|
||||
/// Only relevant if the libraries are being built with TBB support, in which case the default
|
||||
/// enable setting will be true. If no TBB support is compiled in, the default enable state is false.
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
#ifdef CVF_USE_TBB
|
||||
bool TBBControl::sm_useTBB = true;
|
||||
#else
|
||||
bool TBBControl::sm_useTBB = false;
|
||||
#endif
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void TBBControl::enable(bool enableTBB)
|
||||
{
|
||||
#ifdef CVF_USE_TBB
|
||||
sm_useTBB = enableTBB;
|
||||
#else
|
||||
CVF_UNUSED(enableTBB);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool TBBControl::isEnabled()
|
||||
{
|
||||
return sm_useTBB;
|
||||
}
|
||||
|
||||
|
||||
} // namespace cvf
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Static wrapper class to control usage of TBB
|
||||
//
|
||||
//==================================================================================================
|
||||
class TBBControl
|
||||
{
|
||||
public:
|
||||
static void enable(bool enableTBB);
|
||||
static bool isEnabled();
|
||||
|
||||
private:
|
||||
static bool sm_useTBB;
|
||||
};
|
||||
|
||||
|
||||
} // cvf
|
||||
|
||||
|
||||
@@ -0,0 +1,257 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfTimer.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 4668)
|
||||
#include <windows.h>
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
#ifdef CVF_LINUX
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#if defined(CVF_IOS) || defined(CVF_OSX)
|
||||
#include "mach/mach_time.h"
|
||||
#endif
|
||||
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
//
|
||||
// PrivateTimerState
|
||||
//
|
||||
//=================================================================================================
|
||||
#ifdef WIN32
|
||||
class PrivateTimerState
|
||||
{
|
||||
public:
|
||||
PrivateTimerState()
|
||||
{
|
||||
m_ticksPerSecond = 0;
|
||||
m_startTick = 0;
|
||||
m_lastLapTick = 0;
|
||||
|
||||
LARGE_INTEGER freq;
|
||||
if (QueryPerformanceFrequency(&freq))
|
||||
{
|
||||
m_ticksPerSecond = freq.QuadPart;
|
||||
}
|
||||
}
|
||||
|
||||
__int64 m_ticksPerSecond;
|
||||
__int64 m_startTick;
|
||||
__int64 m_lastLapTick;
|
||||
};
|
||||
#endif //WIN32
|
||||
|
||||
#ifdef CVF_LINUX
|
||||
class PrivateTimerState
|
||||
{
|
||||
public:
|
||||
PrivateTimerState()
|
||||
{
|
||||
m_timeStart.tv_sec = 0;
|
||||
m_timeStart.tv_nsec = 0;
|
||||
m_timeMark.tv_sec = 0;
|
||||
m_timeMark.tv_nsec = 0;
|
||||
}
|
||||
|
||||
timespec m_timeStart;
|
||||
timespec m_timeMark;
|
||||
};
|
||||
#endif // CVF_LINUX
|
||||
|
||||
|
||||
#if defined(CVF_IOS) || defined(CVF_OSX)
|
||||
class PrivateTimerState
|
||||
{
|
||||
public:
|
||||
PrivateTimerState()
|
||||
{
|
||||
mach_timebase_info(&m_info);
|
||||
m_startTime = 0;
|
||||
m_lastLapTime = 0;
|
||||
}
|
||||
|
||||
mach_timebase_info_data_t m_info;
|
||||
uint64_t m_startTime;
|
||||
uint64_t m_lastLapTime;
|
||||
};
|
||||
#endif // CVF_IOS || CVF_OSX
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Static helper on Linux to compute difference between two timespecs
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#ifdef CVF_LINUX
|
||||
static timespec ComputeTimespecDiff(const timespec start, const timespec end)
|
||||
{
|
||||
timespec temp;
|
||||
if ((end.tv_nsec - start.tv_nsec) < 0)
|
||||
{
|
||||
temp.tv_sec = end.tv_sec - start.tv_sec - 1;
|
||||
temp.tv_nsec = 1000000000 + end.tv_nsec-start.tv_nsec;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp.tv_sec = end.tv_sec - start.tv_sec;
|
||||
temp.tv_nsec = end.tv_nsec - start.tv_nsec;
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::Timer
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// Timer class
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Start the timer.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Timer::Timer()
|
||||
{
|
||||
m_timerState = new PrivateTimerState;
|
||||
|
||||
restart();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Cleanup
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Timer::~Timer()
|
||||
{
|
||||
delete m_timerState;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Restart timer and laptime
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void Timer::restart()
|
||||
{
|
||||
CVF_ASSERT(m_timerState);
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
LARGE_INTEGER tick;
|
||||
QueryPerformanceCounter(&tick);
|
||||
m_timerState->m_startTick = tick.QuadPart;
|
||||
m_timerState->m_lastLapTick = m_timerState->m_startTick;
|
||||
|
||||
#elif CVF_LINUX
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &m_timerState->m_timeStart);
|
||||
m_timerState->m_timeMark = m_timerState->m_timeStart;
|
||||
|
||||
#elif defined(CVF_IOS) || defined(CVF_OSX)
|
||||
|
||||
m_timerState->m_startTime = mach_absolute_time();
|
||||
m_timerState->m_lastLapTime = m_timerState->m_startTime;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the time elapsed since the start, in seconds
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double Timer::time() const
|
||||
{
|
||||
#ifdef WIN32
|
||||
|
||||
if (m_timerState->m_ticksPerSecond == 0) return 0.0;
|
||||
LARGE_INTEGER nowTick;
|
||||
QueryPerformanceCounter(&nowTick);
|
||||
return static_cast<double>((nowTick.QuadPart - m_timerState->m_startTick))/static_cast<double>(m_timerState->m_ticksPerSecond);
|
||||
|
||||
#elif CVF_LINUX
|
||||
|
||||
timespec timeNow;
|
||||
clock_gettime(CLOCK_MONOTONIC, &timeNow);
|
||||
timespec timeDiff = ComputeTimespecDiff(m_timerState->m_timeStart, timeNow);
|
||||
double timeUsedSec = static_cast<double>(timeDiff.tv_sec) + static_cast<double>(timeDiff.tv_nsec)/1000000000.0;
|
||||
return timeUsedSec;
|
||||
|
||||
#elif defined(CVF_IOS) || defined(CVF_OSX)
|
||||
|
||||
uint64_t timeNow = mach_absolute_time();
|
||||
uint64_t timeUsed = timeNow - m_timerState->m_startTime;
|
||||
timeUsed *= m_timerState->m_info.numer;
|
||||
uint64_t timeUsedNanoSec = timeUsed/m_timerState->m_info.denom;
|
||||
double timeUsedSec = timeUsedNanoSec/1.0e9;
|
||||
return timeUsedSec;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get elapsed time since last lap, in seconds
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double Timer::lapTime()
|
||||
{
|
||||
#ifdef WIN32
|
||||
|
||||
if (m_timerState->m_ticksPerSecond == 0) return 0.0;
|
||||
LARGE_INTEGER nowTick;
|
||||
QueryPerformanceCounter(&nowTick);
|
||||
double lapTime = static_cast<double>((nowTick.QuadPart - m_timerState->m_lastLapTick))/static_cast<double>(m_timerState->m_ticksPerSecond);
|
||||
m_timerState->m_lastLapTick = nowTick.QuadPart;
|
||||
|
||||
#elif CVF_LINUX
|
||||
|
||||
timespec timeNow;
|
||||
clock_gettime(CLOCK_MONOTONIC, &timeNow);
|
||||
timespec timeDiff = ComputeTimespecDiff(m_timerState->m_timeMark, timeNow);
|
||||
m_timerState->m_timeMark = timeNow;
|
||||
double lapTime = static_cast<double>(timeDiff.tv_sec) + static_cast<double>(timeDiff.tv_nsec)/1000000000.0;
|
||||
|
||||
#elif defined(CVF_IOS) || defined(CVF_OSX)
|
||||
|
||||
uint64_t timeNow = mach_absolute_time();
|
||||
uint64_t timeUsed = timeNow - m_timerState->m_lastLapTime;
|
||||
timeUsed *= m_timerState->m_info.numer;
|
||||
uint64_t timeUsedNanoSec = timeUsed/m_timerState->m_info.denom;
|
||||
double lapTime = timeUsedNanoSec/1.0e9;
|
||||
m_timerState->m_lastLapTime = timeNow;
|
||||
|
||||
#endif
|
||||
|
||||
return lapTime;
|
||||
}
|
||||
|
||||
|
||||
} // namespace cvf
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfObject.h"
|
||||
|
||||
namespace cvf {
|
||||
|
||||
class PrivateTimerState;
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
//
|
||||
// Timer class
|
||||
//
|
||||
//=================================================================================================
|
||||
class Timer : public Object
|
||||
{
|
||||
public:
|
||||
Timer();
|
||||
~Timer();
|
||||
|
||||
void restart();
|
||||
|
||||
double time() const;
|
||||
double lapTime();
|
||||
|
||||
private:
|
||||
PrivateTimerState* m_timerState;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfTrace.h"
|
||||
#include "cvfSystem.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 4668)
|
||||
#include <windows.h>
|
||||
#pragma warning (pop)
|
||||
#else
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#endif
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::Trace
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// Class for writing debug text to console, DevStudio output window and file (future)
|
||||
///
|
||||
/// TODO: Create file output.
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Write debug text to console, DevStudio output window and file (future)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void Trace::show(String message)
|
||||
{
|
||||
showTraceOutput(message, true);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Write printf formatted debug text to console, DevStudio output window and file (future)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void Trace::show(const char* format, ...)
|
||||
{
|
||||
// Create the printf-style string and send it to the console and trace file
|
||||
// TODO! Note: var-arg is solved locally here, but needs to be revisited e.g. in String class
|
||||
va_list argList;
|
||||
va_start(argList, format);
|
||||
|
||||
const int maxFormatLength = 4000;
|
||||
char temp[maxFormatLength + 1];
|
||||
|
||||
#ifdef WIN32
|
||||
_vsnprintf_s(temp, maxFormatLength, format, argList);
|
||||
#else
|
||||
vsprintf(temp, format, argList);
|
||||
#endif
|
||||
|
||||
va_end(argList);
|
||||
|
||||
showTraceOutput(temp, true);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void Trace::showFileLineNumber(const String& file, int line, const String& message)
|
||||
{
|
||||
String tmp = file + "(" + String(line) + ")";
|
||||
|
||||
if (!message.isEmpty())
|
||||
{
|
||||
tmp += ": msg: " + message;
|
||||
}
|
||||
|
||||
Trace::show(tmp);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Show the trace output in console and DevStudio output window
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void Trace::showTraceOutput(String text, bool addNewLine)
|
||||
{
|
||||
#ifdef WIN32
|
||||
AllocConsole();
|
||||
|
||||
HANDLE hStdOutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
||||
if (hStdOutputHandle)
|
||||
{
|
||||
unsigned long iDum = 0;
|
||||
CharArray ascii = text.toAscii();
|
||||
DWORD stringLength = static_cast<DWORD>(System::strlen(ascii.ptr()));
|
||||
|
||||
WriteConsoleA(hStdOutputHandle, ascii.ptr(), stringLength, &iDum, NULL);
|
||||
if (addNewLine) WriteConsole(hStdOutputHandle, "\n", 1, &iDum, NULL);
|
||||
}
|
||||
#else
|
||||
fprintf(stderr, "%s", text.toAscii().ptr());
|
||||
if (addNewLine)
|
||||
{
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
// Show output in "Output window" in Visual Studio
|
||||
#if defined(WIN32) && defined(_DEBUG)
|
||||
// Alternativly use OutputDebugStringA(text.toAscii().ptr()); if this does not work on some platforms
|
||||
_RPT0(_CRT_WARN, text.toAscii().ptr());
|
||||
if (addNewLine)
|
||||
{
|
||||
_RPT0(_CRT_WARN, "\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
} // namespace cvf
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfString.h"
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
//
|
||||
// Trace class
|
||||
//
|
||||
//=================================================================================================
|
||||
class Trace
|
||||
{
|
||||
public:
|
||||
static void show(String message);
|
||||
static void show(const char* format, ...);
|
||||
static void showFileLineNumber(const String& file, int line, const String& message);
|
||||
|
||||
private:
|
||||
static void showTraceOutput(String text, bool addNewLine);
|
||||
};
|
||||
|
||||
#define CVF_TRACE_FILELINE Trace::showFileLineNumber(__FILE__, __LINE__, "");
|
||||
#define CVF_TRACE_FILELINE_MSG(message) Trace::showFileLineNumber(__FILE__, __LINE__, message);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfVector4.h"
|
||||
#include "cvfColor4.h"
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Abstract base class for templated read-only array that returns elements by value
|
||||
//
|
||||
//==================================================================================================
|
||||
template <typename T>
|
||||
class ValueArray
|
||||
{
|
||||
public:
|
||||
virtual ~ValueArray() {}
|
||||
virtual T val(size_t index) const = 0;
|
||||
virtual size_t size() const = 0;
|
||||
};
|
||||
|
||||
|
||||
typedef ValueArray<int> IntValueArray;
|
||||
typedef ValueArray<uint> UIntValueArray;
|
||||
typedef ValueArray<ushort> UShortValueArray;
|
||||
typedef ValueArray<ubyte> UByteValueArray;
|
||||
typedef ValueArray<float> FloatValueArray;
|
||||
typedef ValueArray<double> DoubleValueArray;
|
||||
typedef ValueArray<Vec2f> Vec2fValueArray;
|
||||
typedef ValueArray<Vec3f> Vec3fValueArray;
|
||||
typedef ValueArray<Vec3d> Vec3dValueArray;
|
||||
typedef ValueArray<Color3ub> Color3ubValueArray;
|
||||
typedef ValueArray<Color3f> Color3fValueArray;
|
||||
typedef ValueArray<Color4ub> Color4ubValueArray;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfVector2.h"
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
template<> Vector2<double> const Vector2<double>::UNDEFINED(UNDEFINED_DOUBLE, UNDEFINED_DOUBLE);
|
||||
template<> Vector2<float> const Vector2<float>::UNDEFINED(UNDEFINED_FLOAT, UNDEFINED_FLOAT);
|
||||
template<> Vector2<int> const Vector2<int>::UNDEFINED(UNDEFINED_INT, UNDEFINED_INT);
|
||||
|
||||
|
||||
} // namespace cvf
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfMath.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Vector class for 2D vectors
|
||||
//
|
||||
//==================================================================================================
|
||||
template<typename S>
|
||||
class Vector2
|
||||
{
|
||||
public:
|
||||
Vector2() {}
|
||||
Vector2(S x, S y);
|
||||
Vector2(const Vector2& other);
|
||||
|
||||
template<typename T>
|
||||
explicit Vector2(const T& other);
|
||||
|
||||
inline Vector2& operator=(const Vector2& rhs);
|
||||
inline bool operator==(const Vector2& rhs) const;
|
||||
inline bool operator!=(const Vector2& rhs) const;
|
||||
|
||||
inline const Vector2 operator+(const Vector2& rhs) const;
|
||||
inline const Vector2 operator-(const Vector2& rhs) const;
|
||||
inline const Vector2 operator*(S scalar) const;
|
||||
inline const Vector2 operator/(S scalar) const;
|
||||
|
||||
template<typename T>
|
||||
friend inline const Vector2<T> operator*(T scalar, const Vector2<T>& rhs);
|
||||
|
||||
inline const Vector2 operator-() const;
|
||||
|
||||
inline Vector2& operator+=(const Vector2& rhs);
|
||||
inline Vector2& operator-=(const Vector2& rhs);
|
||||
inline Vector2& operator*=(S scalar);
|
||||
inline Vector2& operator/=(S scalar);
|
||||
|
||||
inline const S& operator[](int index) const; // Get component 0 or 1. E.g. x = v[0];
|
||||
inline S& operator[](int index); // Set component 0 or 1. E.g. v[0] = x;
|
||||
|
||||
inline S operator*(const Vector2& rhs) const; // Dot product
|
||||
|
||||
inline const S& x() const { return m_v[0]; } ///< Get the X element of the vector
|
||||
inline const S& y() const { return m_v[1]; } ///< Get the Y element of the vector
|
||||
inline S& x() { return m_v[0]; } ///< Get a reference to the X element of the vector. E.g. x() = 1;
|
||||
inline S& y() { return m_v[1]; } ///< Get a reference to the Y element of the vector. E.g. y() = 2;
|
||||
|
||||
inline S* ptr() { return m_v; } ///< Get a raw pointer to the internal c array of type S.
|
||||
inline const S* ptr() const { return m_v; } ///< Get a const raw pointer to the internal c array of type S.
|
||||
|
||||
inline void set(S x, S y);
|
||||
inline void setZero();
|
||||
inline bool isZero() const;
|
||||
inline bool isUndefined() const;
|
||||
|
||||
template<typename T>
|
||||
void set(const T& other);
|
||||
|
||||
bool normalize();
|
||||
const Vector2 getNormalized(bool* normalizationOK = NULL) const;
|
||||
|
||||
inline S length() const;
|
||||
inline S lengthSquared() const;
|
||||
bool setLength(S newLength);
|
||||
|
||||
public:
|
||||
static const Vector2 X_AXIS; ///< X axis vector <1, 0>
|
||||
static const Vector2 Y_AXIS; ///< Y axis vector <0, 1>
|
||||
static const Vector2 ZERO; ///< Null vector <0, 0>
|
||||
static const Vector2 UNDEFINED; ///< Undefined vector
|
||||
|
||||
private:
|
||||
S m_v[2];
|
||||
};
|
||||
|
||||
typedef Vector2<float> Vec2f; ///< A vector with float components
|
||||
typedef Vector2<double> Vec2d; ///< A vector with double components
|
||||
typedef Vector2<int> Vec2i; ///< A vector with int components
|
||||
typedef Vector2<uint> Vec2ui; ///< A vector with uint components
|
||||
typedef Vector2<ushort> Vec2us; ///< A vector with ushort components
|
||||
|
||||
}
|
||||
|
||||
#include "cvfVector2.inl"
|
||||
@@ -0,0 +1,432 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::Vector2
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// Templated vector class for a 2 component vector.
|
||||
///
|
||||
/// Three ready-to-use typedefs are defined:\n
|
||||
/// - cvf::Vec2f (Vector2<float>)
|
||||
/// - cvf::Vec2d (Vector2<double>)
|
||||
/// - cvf::Vec2i (Vector2<int>)
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
template<typename S> Vector2<S> const Vector2<S>::X_AXIS(1, 0);
|
||||
template<typename S> Vector2<S> const Vector2<S>::Y_AXIS(0, 1);
|
||||
template<typename S> Vector2<S> const Vector2<S>::ZERO(0, 0);
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set the vector to <x,y>
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
Vector2<S>::Vector2(S x, S y)
|
||||
{
|
||||
m_v[0] = x;
|
||||
m_v[1] = y;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set the vector to the same as other
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
Vector2<S>::Vector2(const Vector2& other)
|
||||
{
|
||||
*this = other;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// An explicit cast constructor to convert from one vector type to another.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
template<typename T>
|
||||
Vector2<S>::Vector2(const T& other)
|
||||
{
|
||||
m_v[0] = static_cast<S>(other.x());
|
||||
m_v[1] = static_cast<S>(other.y());
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Assign the vector to the contents of other
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
Vector2<S>& Vector2<S>::operator=(const Vector2& other)
|
||||
{
|
||||
m_v[0] = other.m_v[0];
|
||||
m_v[1] = other.m_v[1];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Check if two vectors are equal. An exact match is required.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline bool Vector2<S>::operator==(const Vector2& rhs) const
|
||||
{
|
||||
return (m_v[0] == rhs.m_v[0]) && (m_v[1] == rhs.m_v[1]);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Check if two vectors are different. Returns true if not an exact match
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline bool Vector2<S>::operator!=(const Vector2& rhs) const
|
||||
{
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns the sum of this vector and the rhs vector
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline const Vector2<S> Vector2<S>::operator+(const Vector2& rhs) const
|
||||
{
|
||||
return Vector2(m_v[0]+rhs.m_v[0], m_v[1]+rhs.m_v[1]);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Compute this-rhs and return the result.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline const Vector2<S> Vector2<S>::operator-(const Vector2& rhs) const
|
||||
{
|
||||
return Vector2(m_v[0] - rhs.m_v[0], m_v[1] - rhs.m_v[1]);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Return this vector scaled by the given scalar
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
const Vector2<S> Vector2<S>::operator*(S scalar) const
|
||||
{
|
||||
return Vector2(m_v[0]*scalar, m_v[1]*scalar);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Return vector scaled by the given scalar
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
const Vector2<T> operator*(T scalar, const Vector2<T>& rhs)
|
||||
{
|
||||
// Note that this is a friend function
|
||||
return Vector2<T>(rhs.m_v[0]*scalar, rhs.m_v[1]*scalar);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Return a vector where each component is the corresponding component in this divided by scalar
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
const Vector2<S> Vector2<S>::operator/(S scalar) const
|
||||
{
|
||||
return Vector2(m_v[0]/scalar, m_v[1]/scalar);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Return a vector which is the negation of this
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
const Vector2<S> Vector2<S>::operator-() const
|
||||
{
|
||||
return Vector2(-m_v[0], -m_v[1]);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Add the given vector to this
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline Vector2<S>& Vector2<S>::operator+=(const Vector2& v)
|
||||
{
|
||||
m_v[0] += v.x();
|
||||
m_v[1] += v.y();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Subtract the given vector from this
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline Vector2<S>& Vector2<S>::operator-=(const Vector2& v)
|
||||
{
|
||||
m_v[0] -= v.x();
|
||||
m_v[1] -= v.y();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Scale this with the given scalar. Each component is multiplied with the given value
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline Vector2<S>& Vector2<S>::operator*=(S scalar)
|
||||
{
|
||||
m_v[0] *= scalar;
|
||||
m_v[1] *= scalar;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Divide this with the given scalar. Each component is divided by the given scalar
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline Vector2<S>& Vector2<S>::operator/=(S scalar)
|
||||
{
|
||||
m_v[0] /= scalar;
|
||||
m_v[1] /= scalar;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get component 0 or 1. E.g. x = v[0];
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline const S& Vector2<S>::operator[](int index) const
|
||||
{
|
||||
CVF_TIGHT_ASSERT(index >= 0);
|
||||
CVF_TIGHT_ASSERT(index < 2);
|
||||
|
||||
return m_v[index];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set component 0 or 1. E.g. v[0] = x;
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline S& Vector2<S>::operator[](int index)
|
||||
{
|
||||
CVF_TIGHT_ASSERT(index >= 0);
|
||||
CVF_TIGHT_ASSERT(index < 2);
|
||||
|
||||
return m_v[index];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Compute the dot product of this and rhs and return the result (scalar)
|
||||
///
|
||||
/// Formula:
|
||||
/// \code
|
||||
/// S = tx*rx + ty*ry
|
||||
/// \endcode
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline S Vector2<S>::operator*(const Vector2& rhs) const
|
||||
{
|
||||
return m_v[0]*rhs.m_v[0] + m_v[1]*rhs.m_v[1];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set the vector from the other vector (of different type). Cast each component to convert it.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
template<typename T>
|
||||
void Vector2<S>::set(const T& other)
|
||||
{
|
||||
m_v[0] = static_cast<S>(other.x());
|
||||
m_v[1] = static_cast<S>(other.y());
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the length of the vector
|
||||
///
|
||||
/// Formula:
|
||||
/// \code
|
||||
/// len = sqrt(x*x + y*y)
|
||||
/// \endcode
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline S Vector2<S>::length() const
|
||||
{
|
||||
return Math::sqrt(m_v[0]*m_v[0] + m_v[1]*m_v[1]);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the squared length (L2) of the vector
|
||||
///
|
||||
/// Formula:
|
||||
/// \code
|
||||
/// len = x*x + y*y
|
||||
/// \endcode
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline S Vector2<S>::lengthSquared() const
|
||||
{
|
||||
return m_v[0]*m_v[0] + m_v[1]*m_v[1];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set the length of the vector to \a newLength.
|
||||
///
|
||||
/// \sa Vector3::setLength()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
bool Vector2<S>::setLength(S newLength)
|
||||
{
|
||||
CVF_ASSERT(newLength >= 0);
|
||||
|
||||
S currLen = length();
|
||||
|
||||
if (currLen > std::numeric_limits<S>::epsilon() && newLength > 0)
|
||||
{
|
||||
S scale = newLength/currLen;
|
||||
m_v[0] *= scale;
|
||||
m_v[1] *= scale;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
setZero();
|
||||
|
||||
return (newLength == 0) ? true : false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Normalize the vector (make sure the length is 1.0).
|
||||
///
|
||||
/// \return Returns true if normalization was possible. Returns false if length is zero or a NaN vector.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
bool Vector2<S>::normalize()
|
||||
{
|
||||
S len = length();
|
||||
if (len > 0.0)
|
||||
{
|
||||
// Precompute 1/length and do multiplication instead of division
|
||||
S oneOverLen = (static_cast<S>(1.0)/len);
|
||||
m_v[0] *= oneOverLen;
|
||||
m_v[1] *= oneOverLen;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Might be NaN, so set it to zero
|
||||
m_v[0] = 0;
|
||||
m_v[1] = 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns a normalized version of the current vector. The vector is unchanged.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
const Vector2<S> Vector2<S>::getNormalized(bool* normalizationOK) const
|
||||
{
|
||||
S len = length();
|
||||
if (len > 0.0)
|
||||
{
|
||||
if (normalizationOK) *normalizationOK = true;
|
||||
|
||||
S oneOverLen = (static_cast<S>(1.0)/len);
|
||||
return Vector2<S>(m_v[0]*oneOverLen, m_v[1]*oneOverLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (normalizationOK) *normalizationOK = false;
|
||||
return Vector2<S>::ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set all components to 0
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline void Vector2<S>::setZero()
|
||||
{
|
||||
m_v[0] = 0;
|
||||
m_v[1] = 0;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Check if all components are zero (exact match)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline bool Vector2<S>::isZero() const
|
||||
{
|
||||
return (m_v[0] == 0) && (m_v[1] == 0);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Check if vector is undefined
|
||||
///
|
||||
/// \return Returns true if any one of the components is undefined
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline bool Vector2<S>::isUndefined() const
|
||||
{
|
||||
if (Math::isUndefined(m_v[0]) ||
|
||||
Math::isUndefined(m_v[1]))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set the components of the vector
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline void Vector2<S>::set(S x, S y)
|
||||
{
|
||||
m_v[0] = x;
|
||||
m_v[1] = y;
|
||||
}
|
||||
|
||||
|
||||
} // namespace cvf
|
||||
@@ -0,0 +1,32 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfVector3.h"
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
template<> Vector3<double> const Vector3<double>::UNDEFINED(UNDEFINED_DOUBLE, UNDEFINED_DOUBLE, UNDEFINED_DOUBLE);
|
||||
template<> Vector3<float> const Vector3<float>::UNDEFINED(UNDEFINED_FLOAT, UNDEFINED_FLOAT, UNDEFINED_FLOAT);
|
||||
template<> Vector3<int> const Vector3<int>::UNDEFINED(UNDEFINED_INT, UNDEFINED_INT, UNDEFINED_INT);
|
||||
template<> Vector3<size_t> const Vector3<size_t>::UNDEFINED(UNDEFINED_SIZE_T, UNDEFINED_SIZE_T, UNDEFINED_SIZE_T);
|
||||
|
||||
|
||||
} // namespace cvf
|
||||
@@ -0,0 +1,137 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfVector2.h"
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
// Forward declaration of templated matrix class
|
||||
template<typename S>
|
||||
class Matrix4;
|
||||
|
||||
template<typename S>
|
||||
class Matrix3;
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Vector class for 3D vectors
|
||||
//
|
||||
//==================================================================================================
|
||||
template<typename S>
|
||||
class Vector3
|
||||
{
|
||||
public:
|
||||
Vector3() {}
|
||||
Vector3(S x, S y, S z);
|
||||
Vector3(const Vector3& other);
|
||||
|
||||
explicit Vector3(const Vector2<S>& other);
|
||||
Vector3(const Vector2<S>& other, S z);
|
||||
|
||||
template<typename T>
|
||||
explicit Vector3(const T& other);
|
||||
|
||||
inline Vector3& operator=(const Vector3& rhs);
|
||||
inline bool operator==(const Vector3& rhs) const;
|
||||
inline bool operator!=(const Vector3& rhs) const;
|
||||
|
||||
inline const Vector3 operator+(const Vector3& rhs) const;
|
||||
inline const Vector3 operator-(const Vector3& rhs) const;
|
||||
inline const Vector3 operator*(S scalar) const;
|
||||
inline const Vector3 operator/(S scalar) const;
|
||||
|
||||
template<typename T>
|
||||
friend inline const Vector3<T> operator*(T scalar, const Vector3<T>& rhs);
|
||||
|
||||
inline const Vector3 operator-() const;
|
||||
|
||||
inline Vector3& operator+=(const Vector3& rhs);
|
||||
inline Vector3& operator-=(const Vector3& rhs);
|
||||
inline Vector3& operator*=(S scalar);
|
||||
inline Vector3& operator/=(S scalar);
|
||||
|
||||
inline const S& operator[](int index) const; // Get component 0,1,2. E.g. x = v[0];
|
||||
inline S& operator[](int index); // Set component 0,1,2. E.g. v[0] = x;
|
||||
|
||||
inline S operator*(const Vector3& rhs) const; // Dot product
|
||||
inline const Vector3 operator^(const Vector3& rhs) const; // Cross product
|
||||
|
||||
inline const S& x() const { return m_v[0]; } ///< Get the X element of the vector
|
||||
inline const S& y() const { return m_v[1]; } ///< Get the Y element of the vector
|
||||
inline const S& z() const { return m_v[2]; } ///< Get the Z element of the vector
|
||||
inline S& x() { return m_v[0]; } ///< Get a reference to the X element of the vector. E.g. x() = 1;
|
||||
inline S& y() { return m_v[1]; } ///< Get a reference to the Y element of the vector. E.g. y() = 2;
|
||||
inline S& z() { return m_v[2]; } ///< Get a reference to the Z element of the vector. E.g. z() = 3;
|
||||
|
||||
inline S* ptr() { return m_v; } ///< Get a raw pointer to the internal c array of type S.
|
||||
inline const S* ptr() const { return m_v; } ///< Get a const raw pointer to the internal c array of type S.
|
||||
|
||||
inline void set(S x, S y, S z);
|
||||
inline void setZero();
|
||||
inline bool isZero() const;
|
||||
inline bool isUndefined() const;
|
||||
|
||||
template<typename T>
|
||||
void set(const T& other);
|
||||
|
||||
bool normalize();
|
||||
const Vector3 getNormalized(bool* normalizationOK = NULL) const;
|
||||
|
||||
inline S length() const;
|
||||
inline S lengthSquared() const;
|
||||
bool setLength(S newLength);
|
||||
|
||||
inline S pointDistance(const Vector3& otherPoint) const;
|
||||
inline S pointDistanceSquared(const Vector3& otherPoint) const;
|
||||
|
||||
void transformPoint(const Matrix4<S>& m);
|
||||
const Vector3 getTransformedPoint(const Matrix4<S>& m) const;
|
||||
|
||||
void transformVector(const Matrix4<S>& m);
|
||||
const Vector3 getTransformedVector(const Matrix4<S>& m) const;
|
||||
void transformVector(const Matrix3<S>& m);
|
||||
const Vector3 getTransformedVector(const Matrix3<S>& m) const;
|
||||
|
||||
bool createOrthonormalBasis(int mapToAxis, Vector3<S>* uAxis, Vector3<S>* vAxis, Vector3<S>* wAxis) const;
|
||||
const Vector3 perpendicularVector(bool* perpendicularOK = NULL) const;
|
||||
|
||||
public:
|
||||
static const Vector3 X_AXIS; ///< X axis vector <1, 0, 0>
|
||||
static const Vector3 Y_AXIS; ///< Y axis vector <0, 1, 0>
|
||||
static const Vector3 Z_AXIS; ///< Z axis vector <0, 0, 1>
|
||||
static const Vector3 ZERO; ///< Null vector <0, 0, 0>
|
||||
static const Vector3 UNDEFINED; ///< Undefined vector
|
||||
|
||||
private:
|
||||
S m_v[3];
|
||||
};
|
||||
|
||||
typedef Vector3<float> Vec3f; ///< A vector with float components
|
||||
typedef Vector3<double> Vec3d; ///< A vector with double components
|
||||
typedef Vector3<int> Vec3i; ///< A vector with int components
|
||||
typedef Vector3<uint> Vec3ui; ///< A vector with uint components
|
||||
typedef Vector3<size_t> Vec3st; ///< A vector with size_t components
|
||||
|
||||
}
|
||||
|
||||
#include "cvfVector3.inl"
|
||||
@@ -0,0 +1,707 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::Vector3
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// Templated vector class for a 3 component vector.
|
||||
///
|
||||
/// Three ready-to-use typedefs are defined:\n
|
||||
/// - cvf::Vec3f (Vector3<float>)
|
||||
/// - cvf::Vec3d (Vector3<double>)
|
||||
/// - cvf::Vec3i (Vector3<int>)
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
template<typename S> Vector3<S> const Vector3<S>::X_AXIS(1,0,0);
|
||||
template<typename S> Vector3<S> const Vector3<S>::Y_AXIS(0,1,0);
|
||||
template<typename S> Vector3<S> const Vector3<S>::Z_AXIS(0,0,1);
|
||||
template<typename S> Vector3<S> const Vector3<S>::ZERO(0,0,0);
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set the vector to <x,y,z>
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
Vector3<S>::Vector3(S x, S y, S z)
|
||||
{
|
||||
m_v[0] = x;
|
||||
m_v[1] = y;
|
||||
m_v[2] = z;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set the vector to the same as other
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
Vector3<S>::Vector3(const Vector3& other)
|
||||
{
|
||||
*this = other;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// An explicit cast constructor to convert from one vector type to another.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
template<typename T>
|
||||
Vector3<S>::Vector3(const T& other)
|
||||
{
|
||||
m_v[0] = static_cast<S>(other.x());
|
||||
m_v[1] = static_cast<S>(other.y());
|
||||
m_v[2] = static_cast<S>(other.z());
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Explicit constructor from 2D vector.
|
||||
///
|
||||
/// Will initialize x and y components from the 2D vector, z will be set to 0.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
Vector3<S>::Vector3(const Vector2<S>& other)
|
||||
{
|
||||
m_v[0] = other.x();
|
||||
m_v[1] = other.y();
|
||||
m_v[2] = 0.0;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Constructor
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
Vector3<S>::Vector3(const Vector2<S>& other, S z)
|
||||
{
|
||||
m_v[0] = other.x();
|
||||
m_v[1] = other.y();
|
||||
m_v[2] = z;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Assign the vector to the contents of other
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
Vector3<S>& Vector3<S>::operator=(const Vector3& other)
|
||||
{
|
||||
m_v[0] = other.m_v[0];
|
||||
m_v[1] = other.m_v[1];
|
||||
m_v[2] = other.m_v[2];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Check if two vectors are equal. An exact match is required.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline bool Vector3<S>::operator==(const Vector3& rhs) const
|
||||
{
|
||||
return (m_v[0] == rhs.m_v[0]) && (m_v[1] == rhs.m_v[1]) && (m_v[2] == rhs.m_v[2]);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Check if two vectors are different. Returns true if not an exact match
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline bool Vector3<S>::operator!=(const Vector3& rhs) const
|
||||
{
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns the sum of this vector and the rhs vector
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline const Vector3<S> Vector3<S>::operator+(const Vector3& rhs) const
|
||||
{
|
||||
return Vector3(m_v[0]+rhs.m_v[0], m_v[1]+rhs.m_v[1], m_v[2]+rhs.m_v[2]);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Compute this-rhs and return the result.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline const Vector3<S> Vector3<S>::operator-(const Vector3& rhs) const
|
||||
{
|
||||
return Vector3(m_v[0] - rhs.m_v[0], m_v[1] - rhs.m_v[1], m_v[2] - rhs.m_v[2]);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Return this vector scaled by the given scalar
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
const Vector3<S> Vector3<S>::operator*(S scalar) const
|
||||
{
|
||||
return Vector3(m_v[0]*scalar, m_v[1]*scalar, m_v[2]*scalar);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Return vector scaled by the given scalar
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
const Vector3<T> operator*(T scalar, const Vector3<T>& rhs)
|
||||
{
|
||||
// Note that this is a friend function
|
||||
return Vector3<T>(rhs.m_v[0]*scalar, rhs.m_v[1]*scalar, rhs.m_v[2]*scalar);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Return a vector where each component is the corresponding component in this divided by scalar
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
const Vector3<S> Vector3<S>::operator/(S scalar) const
|
||||
{
|
||||
return Vector3(m_v[0]/scalar, m_v[1]/scalar, m_v[2]/scalar);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Return a vector which is the negation of this
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
const Vector3<S> Vector3<S>::operator-() const
|
||||
{
|
||||
return Vector3(-m_v[0], -m_v[1], -m_v[2]);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Add the given vector to this
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline Vector3<S>& Vector3<S>::operator+=(const Vector3& v)
|
||||
{
|
||||
m_v[0] += v.x();
|
||||
m_v[1] += v.y();
|
||||
m_v[2] += v.z();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Subtract the given vector from this
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline Vector3<S>& Vector3<S>::operator-=(const Vector3& v)
|
||||
{
|
||||
m_v[0] -= v.x();
|
||||
m_v[1] -= v.y();
|
||||
m_v[2] -= v.z();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Scale this with the given scalar. Each component is multiplied with the given value
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline Vector3<S>& Vector3<S>::operator*=(S scalar)
|
||||
{
|
||||
m_v[0] *= scalar;
|
||||
m_v[1] *= scalar;
|
||||
m_v[2] *= scalar;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Divide this with the given scalar. Each component is divided by the given scalar
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline Vector3<S>& Vector3<S>::operator/=(S scalar)
|
||||
{
|
||||
m_v[0] /= scalar;
|
||||
m_v[1] /= scalar;
|
||||
m_v[2] /= scalar;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get component 0,1,2. E.g. x = v[0];
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline const S& Vector3<S>::operator[](int index) const
|
||||
{
|
||||
CVF_TIGHT_ASSERT(index >= 0);
|
||||
CVF_TIGHT_ASSERT(index < 3);
|
||||
|
||||
return m_v[index];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set component 0,1,2. E.g. v[0] = x;
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline S& Vector3<S>::operator[](int index)
|
||||
{
|
||||
CVF_TIGHT_ASSERT(index >= 0);
|
||||
CVF_TIGHT_ASSERT(index < 3);
|
||||
|
||||
return m_v[index];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Compute the dot product of this and rhs and return the result (scalar)
|
||||
///
|
||||
/// Formula:
|
||||
/// \code
|
||||
/// S = tx*rx + ty*ry + tz*rz
|
||||
/// \endcode
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline S Vector3<S>::operator*(const Vector3& rhs) const
|
||||
{
|
||||
return m_v[0]*rhs.m_v[0] + m_v[1]*rhs.m_v[1] + m_v[2]*rhs.m_v[2];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Compute the cross product of this and rhs and return the result (vector)
|
||||
///
|
||||
/// Formula:
|
||||
/// \code
|
||||
/// vec = <ty*rz - tz*ry, tz*rx - tx*rz, tx*ry - ty*rx>
|
||||
/// \endcode
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline const Vector3<S> Vector3<S>::operator^(const Vector3& rhs) const
|
||||
{
|
||||
return Vector3(m_v[1]*rhs.m_v[2] - m_v[2]*rhs.m_v[1], m_v[2]*rhs.m_v[0] - m_v[0]*rhs.m_v[2], m_v[0]*rhs.m_v[1] - m_v[1]*rhs.m_v[0]);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set the vector from the other vector (of different type). Cast each component to convert it.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
template<typename T>
|
||||
void Vector3<S>::set(const T& other)
|
||||
{
|
||||
m_v[0] = static_cast<S>(other.x());
|
||||
m_v[1] = static_cast<S>(other.y());
|
||||
m_v[2] = static_cast<S>(other.z());
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the length of the vector
|
||||
///
|
||||
/// Formula:
|
||||
/// \code
|
||||
/// len = sqrt(x*x + y*y + z*z)
|
||||
/// \endcode
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline S Vector3<S>::length() const
|
||||
{
|
||||
return Math::sqrt(m_v[0]*m_v[0] + m_v[1]*m_v[1] + m_v[2]*m_v[2]);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the squared length (L2) of the vector
|
||||
///
|
||||
/// Formula:
|
||||
/// \code
|
||||
/// len = x*x + y*y + z*z
|
||||
/// \endcode
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline S Vector3<S>::lengthSquared() const
|
||||
{
|
||||
return m_v[0]*m_v[0] + m_v[1]*m_v[1] + m_v[2]*m_v[2];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set the length of the vector to \a newLength.
|
||||
///
|
||||
/// \return The method returns true if scaling was a success. Returns false if the vector was of
|
||||
/// zero length and \a newLength was different from 0.
|
||||
///
|
||||
/// This is the same as calling normalize() and then scaling with \a newLength.
|
||||
/// If the current vector length is 0 or \a newLength is 0, the vector is set to all zeros.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
bool Vector3<S>::setLength(S newLength)
|
||||
{
|
||||
CVF_ASSERT(newLength >= 0);
|
||||
|
||||
S currLen = length();
|
||||
|
||||
if (currLen > std::numeric_limits<S>::epsilon() && newLength > 0)
|
||||
{
|
||||
S scale = newLength/currLen;
|
||||
m_v[0] *= scale;
|
||||
m_v[1] *= scale;
|
||||
m_v[2] *= scale;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
setZero();
|
||||
|
||||
return (newLength == 0) ? true : false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the distance between this point and the point specified in \a otherPoint
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline S Vector3<S>::pointDistance(const Vector3& otherPoint) const
|
||||
{
|
||||
return Math::sqrt(pointDistanceSquared(otherPoint));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the squared distance between this point and the point specified in \a otherPoint
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline S Vector3<S>::pointDistanceSquared(const Vector3& otherPoint) const
|
||||
{
|
||||
S x = otherPoint.m_v[0] - m_v[0];
|
||||
S y = otherPoint.m_v[1] - m_v[1];
|
||||
S z = otherPoint.m_v[2] - m_v[2];
|
||||
|
||||
return (x*x + y*y + z*z);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Normalize the vector (make sure the length is 1.0).
|
||||
///
|
||||
/// \return Returns true if normalization was possible. Returns false if length is zero or a NaN vector.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
bool Vector3<S>::normalize()
|
||||
{
|
||||
S len = length();
|
||||
if (len > 0.0)
|
||||
{
|
||||
// Precompute 1/length and do multiplication instead of division
|
||||
S oneOverLen = (static_cast<S>(1.0)/len);
|
||||
m_v[0] *= oneOverLen;
|
||||
m_v[1] *= oneOverLen;
|
||||
m_v[2] *= oneOverLen;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Might be NaN, so set it to zero
|
||||
m_v[0] = 0;
|
||||
m_v[1] = 0;
|
||||
m_v[2] = 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns a normalized version of the current vector. The vector is unchanged.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
const Vector3<S> Vector3<S>::getNormalized(bool* normalizationOK) const
|
||||
{
|
||||
S len = length();
|
||||
if (len > 0.0)
|
||||
{
|
||||
if (normalizationOK) *normalizationOK = true;
|
||||
|
||||
S oneOverLen = (static_cast<S>(1.0)/len);
|
||||
return Vector3<S>(m_v[0]*oneOverLen, m_v[1]*oneOverLen, m_v[2]*oneOverLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (normalizationOK) *normalizationOK = false;
|
||||
return Vector3<S>::ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set all components to 0
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline void Vector3<S>::setZero()
|
||||
{
|
||||
m_v[0] = 0;
|
||||
m_v[1] = 0;
|
||||
m_v[2] = 0;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Check if all components are zero (exact match)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline bool Vector3<S>::isZero() const
|
||||
{
|
||||
return (m_v[0] == 0) && (m_v[1] == 0) && (m_v[2] == 0);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Check if vector is undefined
|
||||
///
|
||||
/// \return Returns true if any one of the components is undefined
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline bool Vector3<S>::isUndefined() const
|
||||
{
|
||||
if (Math::isUndefined(m_v[0]) ||
|
||||
Math::isUndefined(m_v[1]) ||
|
||||
Math::isUndefined(m_v[2]))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set the components of the vector
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline void Vector3<S>::set(S x, S y, S z)
|
||||
{
|
||||
m_v[0] = x;
|
||||
m_v[1] = y;
|
||||
m_v[2] = z;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Transforms this vector as a point.
|
||||
///
|
||||
/// Transforms this vector as a point by multiplying it with the passed matrix.
|
||||
/// This will both rotate and translate this.
|
||||
/// Assumes the matrix m doesn't contain any perspective projection
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
void Vector3<S>::transformPoint(const Matrix4<S>& m)
|
||||
{
|
||||
const S* pV = m.ptr();
|
||||
|
||||
S valX = pV[0]*x() + pV[4]*y() + pV[8]*z() + pV[12];
|
||||
S valY = pV[1]*x() + pV[5]*y() + pV[9]*z() + pV[13];
|
||||
S valZ = pV[2]*x() + pV[6]*y() + pV[10]*z() + pV[14];
|
||||
|
||||
x() = valX;
|
||||
y() = valY;
|
||||
z() = valZ;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Return this vector transformed as a point (rotation and translation) with the given matrix.
|
||||
/// \sa
|
||||
/// transformPoint
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
const Vector3<S> Vector3<S>::getTransformedPoint(const Matrix4<S>& m) const
|
||||
{
|
||||
Vector3<S> pt(*this);
|
||||
pt.transformPoint(m);
|
||||
return pt;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Transforms this vector as a vector.
|
||||
///
|
||||
/// Transforms this vector as a vector by multiplying it with the passed matrix.
|
||||
/// This will only rotate the vector, but not consider the translation part of the matrix.
|
||||
/// Assumes the matrix m doesn't contain any perspective projection.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
void Vector3<S>::transformVector(const Matrix4<S>& m)
|
||||
{
|
||||
const S* pV = m.ptr();
|
||||
|
||||
S valX = pV[0]*x() + pV[4]*y() + pV[8]*z();
|
||||
S valY = pV[1]*x() + pV[5]*y() + pV[9]*z();
|
||||
S valZ = pV[2]*x() + pV[6]*y() + pV[10]*z();
|
||||
|
||||
x() = valX;
|
||||
y() = valY;
|
||||
z() = valZ;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Return this vector transformed as a vector (rotation only) with the given matrix.
|
||||
/// \sa
|
||||
/// transformVector
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
const Vector3<S> Vector3<S>::getTransformedVector(const Matrix4<S>& m) const
|
||||
{
|
||||
Vector3<S> vec(*this);
|
||||
vec.transformVector(m);
|
||||
return vec;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Transforms this vector.
|
||||
///
|
||||
/// Transforms this vector by multiplying it with the passed matrix.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
void Vector3<S>::transformVector(const Matrix3<S>& m)
|
||||
{
|
||||
const S* pV = m.ptr();
|
||||
|
||||
S valX = pV[0]*x() + pV[3]*y() + pV[6]*z();
|
||||
S valY = pV[1]*x() + pV[4]*y() + pV[7]*z();
|
||||
S valZ = pV[2]*x() + pV[5]*y() + pV[8]*z();
|
||||
|
||||
x() = valX;
|
||||
y() = valY;
|
||||
z() = valZ;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Return this vector transformed with the given matrix.
|
||||
/// \sa
|
||||
/// transformVector
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
const Vector3<S> Vector3<S>::getTransformedVector(const Matrix3<S>& m) const
|
||||
{
|
||||
Vector3<S> vec(*this);
|
||||
vec.transformVector(m);
|
||||
return vec;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/// Create an orthonormal basis from this vector
|
||||
///
|
||||
/// \param mapToAxis Specifies which axis this vector should be mapped onto (0=u, 1=v, 2=w)
|
||||
/// \param uAxis Output u vector
|
||||
/// \param vAxis Output v vector
|
||||
/// \param wAxis Output w vector
|
||||
///
|
||||
/// Will create an orthonormal basis from this vector. The returned u, v and w axes will all be unit
|
||||
/// length and will be perpendicular to each other.
|
||||
/// The vector does not have to be normalized before calling this function.
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
bool Vector3<S>::createOrthonormalBasis(int mapToAxis, Vector3<S>* uAxis, Vector3<S>* vAxis, Vector3<S>* wAxis) const
|
||||
{
|
||||
bool normalizedOK = false;
|
||||
Vector3<S> W = getNormalized(&normalizedOK);
|
||||
if (!normalizedOK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector3<S> U(0, 0, 0);
|
||||
if (Math::abs(W.x()) >= Math::abs(W.y()))
|
||||
{
|
||||
// W.x or W.z component has largest magnitude
|
||||
S length = Math::sqrt(W.x()*W.x() + W.z()*W.z());
|
||||
U.x() = -W.z()/length;
|
||||
U.y() = 0.0;
|
||||
U.z() = +W.x()/length;
|
||||
}
|
||||
else
|
||||
{
|
||||
// W.y or W.z component has largest magnitude
|
||||
S length = Math::sqrt(W.y()*W.y() + W.z()*W.z());
|
||||
U.x() = 0.0;
|
||||
U.y() = +W.z()/length;
|
||||
U.z() = -W.y()/length;
|
||||
}
|
||||
|
||||
// Get V as cross product of WxU
|
||||
// Could be optimized by taking into account the fact that either the y or x component of U will be 0
|
||||
Vector3<S> V = W^U;
|
||||
|
||||
// Algorithm above maps our vector onto W axis
|
||||
// If another axis is requested, we need to shuffle the vectors
|
||||
if (mapToAxis == 0)
|
||||
{
|
||||
if (uAxis) *uAxis = W;
|
||||
if (vAxis) *vAxis = U;
|
||||
if (wAxis) *wAxis = V;
|
||||
}
|
||||
else if (mapToAxis == 1)
|
||||
{
|
||||
if (uAxis) *uAxis = V;
|
||||
if (vAxis) *vAxis = W;
|
||||
if (wAxis) *wAxis = U;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (uAxis) *uAxis = U;
|
||||
if (vAxis) *vAxis = V;
|
||||
if (wAxis) *wAxis = W;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Return a unit length perpendicular vector
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
const Vector3<S> Vector3<S>::perpendicularVector(bool* perpendicularOK) const
|
||||
{
|
||||
Vector3<S> perpendic(0, 0, 0);
|
||||
bool ok = createOrthonormalBasis(0, NULL, &perpendic, NULL);
|
||||
if (perpendicularOK)
|
||||
{
|
||||
*perpendicularOK = ok;
|
||||
}
|
||||
|
||||
return perpendic;
|
||||
}
|
||||
|
||||
|
||||
} // namespace cvf
|
||||
@@ -0,0 +1,32 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfVector4.h"
|
||||
#include "cvfMath.h"
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
template<> Vector4<double> const Vector4<double>::UNDEFINED(UNDEFINED_DOUBLE, UNDEFINED_DOUBLE, UNDEFINED_DOUBLE, UNDEFINED_DOUBLE);
|
||||
template<> Vector4<float> const Vector4<float>::UNDEFINED(UNDEFINED_FLOAT, UNDEFINED_FLOAT, UNDEFINED_FLOAT, UNDEFINED_FLOAT);
|
||||
template<> Vector4<int> const Vector4<int>::UNDEFINED(UNDEFINED_INT, UNDEFINED_INT, UNDEFINED_INT, UNDEFINED_INT);
|
||||
|
||||
|
||||
} // namespace cvf
|
||||
@@ -0,0 +1,105 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfVector3.h"
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Vector class for 3D vectors
|
||||
//
|
||||
//==================================================================================================
|
||||
template<typename S>
|
||||
class Vector4
|
||||
{
|
||||
public:
|
||||
Vector4() {}
|
||||
Vector4(S x, S y, S z, S w);
|
||||
Vector4(const Vector4& other);
|
||||
|
||||
Vector4(const Vector3<S>& other, S w);
|
||||
|
||||
template<typename T>
|
||||
explicit Vector4(const T& other);
|
||||
|
||||
inline Vector4& operator=(const Vector4& rhs);
|
||||
inline bool operator==(const Vector4& rhs) const;
|
||||
inline bool operator!=(const Vector4& rhs) const;
|
||||
|
||||
inline const Vector4 operator+(const Vector4& rhs) const;
|
||||
inline const Vector4 operator-(const Vector4& rhs) const;
|
||||
inline const Vector4 operator*(S scalar) const;
|
||||
inline const Vector4 operator/(S scalar) const;
|
||||
inline const Vector4 operator-() const;
|
||||
|
||||
inline Vector4& operator+=(const Vector4& rhs);
|
||||
inline Vector4& operator-=(const Vector4& rhs);
|
||||
inline Vector4& operator*=(S scalar);
|
||||
inline Vector4& operator/=(S scalar);
|
||||
|
||||
inline const S& operator[](int index) const; // Get component 0,1,2,3. E.g. x = v[0];
|
||||
inline S& operator[](int index); // Set component 0,1,2,3. E.g. v[0] = x;
|
||||
|
||||
inline S operator*(const Vector4& rhs) const; // Dot product
|
||||
|
||||
inline const S& x() const { return m_v[0]; } ///< Get the X element of the vector
|
||||
inline const S& y() const { return m_v[1]; } ///< Get the Y element of the vector
|
||||
inline const S& z() const { return m_v[2]; } ///< Get the Z element of the vector
|
||||
inline const S& w() const { return m_v[3]; } ///< Get the W element of the vector
|
||||
inline S& x() { return m_v[0]; } ///< Get a reference to the X element of the vector. E.g. x() = 1;
|
||||
inline S& y() { return m_v[1]; } ///< Get a reference to the Y element of the vector. E.g. y() = 2;
|
||||
inline S& z() { return m_v[2]; } ///< Get a reference to the Z element of the vector. E.g. z() = 3;
|
||||
inline S& w() { return m_v[3]; } ///< Get a reference to the W element of the vector. E.g. w() = 3;
|
||||
|
||||
inline S* ptr() { return m_v; } ///< Get a raw pointer to the internal c array of type S.
|
||||
inline const S* ptr() const { return m_v; } ///< Get a const raw pointer to the internal c array of type S.
|
||||
|
||||
inline void set(S x, S y, S z, S w);
|
||||
inline void setZero();
|
||||
inline bool isZero() const;
|
||||
|
||||
template<typename T>
|
||||
void set(const T& other);
|
||||
|
||||
bool normalize();
|
||||
Vector4 normalized(bool* normalizationOK = NULL) const;
|
||||
|
||||
inline S length() const;
|
||||
inline S lengthSquared() const;
|
||||
bool setLength(S newLength);
|
||||
|
||||
public:
|
||||
static const Vector4 ZERO; ///< Null vector <0, 0, 0>
|
||||
static const Vector4 UNDEFINED; ///< Undefined vector
|
||||
|
||||
private:
|
||||
S m_v[4];
|
||||
};
|
||||
|
||||
typedef Vector4<float> Vec4f; ///< A vector with float components
|
||||
typedef Vector4<double> Vec4d; ///< A vector with double components
|
||||
typedef Vector4<int> Vec4i; ///< A vector with int components
|
||||
|
||||
}
|
||||
|
||||
#include "cvfVector4.inl"
|
||||
@@ -0,0 +1,440 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::Vector4
|
||||
/// \ingroup Core
|
||||
///
|
||||
/// Templated vector class for a 4 component vector.
|
||||
///
|
||||
/// Three ready-to-use typedefs are defined:\n
|
||||
/// - cvf::Vec4f (Vector4<float>)
|
||||
/// - cvf::Vec4d (Vector4<double>)
|
||||
/// - cvf::Vec4i (Vector4<int>)
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
template<typename S> Vector4<S> const Vector4<S>::ZERO(0,0,0,0);
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set the vector to <x,y,z>
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
Vector4<S>::Vector4(S x, S y, S z, S w)
|
||||
{
|
||||
m_v[0] = x;
|
||||
m_v[1] = y;
|
||||
m_v[2] = z;
|
||||
m_v[3] = w;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set the vector to the same as other
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
Vector4<S>::Vector4(const Vector4& other)
|
||||
{
|
||||
*this = other;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// An explicit cast constructor to convert from one vector type to another.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
template<typename T>
|
||||
Vector4<S>::Vector4(const T& other)
|
||||
{
|
||||
m_v[0] = static_cast<S>(other.x());
|
||||
m_v[1] = static_cast<S>(other.y());
|
||||
m_v[2] = static_cast<S>(other.z());
|
||||
m_v[3] = static_cast<S>(other.w());
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Assign the vector to the contents of other
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
Vector4<S>& Vector4<S>::operator=(const Vector4& other)
|
||||
{
|
||||
m_v[0] = other.m_v[0];
|
||||
m_v[1] = other.m_v[1];
|
||||
m_v[2] = other.m_v[2];
|
||||
m_v[3] = other.m_v[3];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
Vector4<S>::Vector4(const Vector3<S>& other, S w)
|
||||
{
|
||||
m_v[0] = other.x();
|
||||
m_v[1] = other.y();
|
||||
m_v[2] = other.z();
|
||||
m_v[3] = w;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Check if two vectors are equal. An exact match is required.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline bool Vector4<S>::operator==(const Vector4& rhs) const
|
||||
{
|
||||
return (m_v[0] == rhs.m_v[0]) && (m_v[1] == rhs.m_v[1]) && (m_v[2] == rhs.m_v[2]) && (m_v[3] == rhs.m_v[3]);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Check if two vectors are different. Returns true if not an exact match
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline bool Vector4<S>::operator!=(const Vector4& rhs) const
|
||||
{
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns the sum of this vector and the rhs vector
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline const Vector4<S> Vector4<S>::operator+(const Vector4& rhs) const
|
||||
{
|
||||
return Vector4(m_v[0] + rhs.m_v[0], m_v[1] + rhs.m_v[1], m_v[2] + rhs.m_v[2], m_v[3] + rhs.m_v[3]);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Compute this-rhs and return the result.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline const Vector4<S> Vector4<S>::operator-(const Vector4& rhs) const
|
||||
{
|
||||
return Vector4(m_v[0] - rhs.m_v[0], m_v[1] - rhs.m_v[1], m_v[2] - rhs.m_v[2], m_v[3] - rhs.m_v[3]);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Return this vector scaled by the given scalar
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
const Vector4<S> Vector4<S>::operator*(S scalar) const
|
||||
{
|
||||
return Vector4(m_v[0]*scalar, m_v[1]*scalar, m_v[2]*scalar, m_v[3]*scalar);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Return a vector where each component is the corresponding component in this divided by scalar
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
const Vector4<S> Vector4<S>::operator/(S scalar) const
|
||||
{
|
||||
return Vector4(m_v[0]/scalar, m_v[1]/scalar, m_v[2]/scalar, m_v[3]/scalar);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Return a vector which is the negation of this
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
const Vector4<S> Vector4<S>::operator-() const
|
||||
{
|
||||
return Vector4(-m_v[0], -m_v[1], -m_v[2], -m_v[3]);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Add the given vector to this
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline Vector4<S>& Vector4<S>::operator+=(const Vector4& v)
|
||||
{
|
||||
m_v[0] += v.x();
|
||||
m_v[1] += v.y();
|
||||
m_v[2] += v.z();
|
||||
m_v[3] += v.w();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Subtract the given vector from this
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline Vector4<S>& Vector4<S>::operator-=(const Vector4& v)
|
||||
{
|
||||
m_v[0] -= v.x();
|
||||
m_v[1] -= v.y();
|
||||
m_v[2] -= v.z();
|
||||
m_v[3] -= v.w();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Scale this with the given scalar. Each component is multiplied with the given value
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline Vector4<S>& Vector4<S>::operator*=(S scalar)
|
||||
{
|
||||
m_v[0] *= scalar;
|
||||
m_v[1] *= scalar;
|
||||
m_v[2] *= scalar;
|
||||
m_v[3] *= scalar;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Divide this with the given scalar. Each component is divided by the given scalar
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline Vector4<S>& Vector4<S>::operator/=(S scalar)
|
||||
{
|
||||
m_v[0] /= scalar;
|
||||
m_v[1] /= scalar;
|
||||
m_v[2] /= scalar;
|
||||
m_v[3] /= scalar;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get component 0,1,2,3. E.g. x = v[0];
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline const S& Vector4<S>::operator[](int index) const
|
||||
{
|
||||
CVF_TIGHT_ASSERT(index >= 0);
|
||||
CVF_TIGHT_ASSERT(index < 4);
|
||||
|
||||
return m_v[index];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set component 0,1,2,3. E.g. v[0] = x;
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline S& Vector4<S>::operator[](int index)
|
||||
{
|
||||
CVF_TIGHT_ASSERT(index >= 0);
|
||||
CVF_TIGHT_ASSERT(index < 4);
|
||||
|
||||
return m_v[index];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Compute the dot product of this and rhs and return the result (scalar)
|
||||
///
|
||||
/// Formula:
|
||||
/// \code
|
||||
/// S = tx*rx + ty*ry + tz*rz + tw*rw
|
||||
/// \endcode
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline S Vector4<S>::operator*(const Vector4& rhs) const
|
||||
{
|
||||
return m_v[0]*rhs.m_v[0] + m_v[1]*rhs.m_v[1] + m_v[2]*rhs.m_v[2] + m_v[3]*rhs.m_v[3];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set the vector from the other vector (of different type). Cast each component to convert it.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
template<typename T>
|
||||
void Vector4<S>::set(const T& other)
|
||||
{
|
||||
m_v[0] = static_cast<S>(other.x());
|
||||
m_v[1] = static_cast<S>(other.y());
|
||||
m_v[2] = static_cast<S>(other.z());
|
||||
m_v[3] = static_cast<S>(other.w());
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the length of the vector
|
||||
///
|
||||
/// Formula:
|
||||
/// \code
|
||||
/// len = sqrt(x*x + y*y + z*z)
|
||||
/// \endcode
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline S Vector4<S>::length() const
|
||||
{
|
||||
return Math::sqrt(m_v[0]*m_v[0] + m_v[1]*m_v[1] + m_v[2]*m_v[2] + m_v[3]*m_v[3]);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the squared length (L2) of the vector
|
||||
///
|
||||
/// Formula:
|
||||
/// \code
|
||||
/// len = x*x + y*y + z*z
|
||||
/// \endcode
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline S Vector4<S>::lengthSquared() const
|
||||
{
|
||||
return m_v[0]*m_v[0] + m_v[1]*m_v[1] + m_v[2]*m_v[2] + m_v[3]*m_v[3];
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set the length of the vector to \a newLength.
|
||||
///
|
||||
/// \sa Vector3::setLength()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
bool Vector4<S>::setLength(S newLength)
|
||||
{
|
||||
CVF_ASSERT(newLength >= 0);
|
||||
|
||||
S currLen = length();
|
||||
|
||||
if (currLen > std::numeric_limits<S>::epsilon() && newLength > 0)
|
||||
{
|
||||
S scale = newLength/currLen;
|
||||
m_v[0] *= scale;
|
||||
m_v[1] *= scale;
|
||||
m_v[2] *= scale;
|
||||
m_v[3] *= scale;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
setZero();
|
||||
|
||||
return (newLength == 0) ? true : false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Normalize the vector (make sure the length is 1.0).
|
||||
/// Returns true if normalization was possible. Returns false if length is zero or a NaN vector.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
bool Vector4<S>::normalize()
|
||||
{
|
||||
S len = length();
|
||||
if (len > 0.0)
|
||||
{
|
||||
// Precompute 1/length and do multiplication instead of division
|
||||
S oneOverLen = (static_cast<S>(1.0)/len);
|
||||
m_v[0] *= oneOverLen;
|
||||
m_v[1] *= oneOverLen;
|
||||
m_v[2] *= oneOverLen;
|
||||
m_v[3] *= oneOverLen;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Might be NaN, so set it to zero
|
||||
m_v[0] = 0.0f;
|
||||
m_v[1] = 0.0f;
|
||||
m_v[2] = 0.0f;
|
||||
m_v[3] = 0.0f;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns a normalized version of the current vector. The vector is unchanged.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
Vector4<S> Vector4<S>::normalized(bool* normalizationOK) const
|
||||
{
|
||||
S len = length();
|
||||
if (len > 0.0)
|
||||
{
|
||||
if (normalizationOK) *normalizationOK = true;
|
||||
|
||||
S oneOverLen = (static_cast<S>(1.0)/len);
|
||||
return Vector4<S>(m_v[0]*oneOverLen, m_v[1]*oneOverLen, m_v[2]*oneOverLen, m_v[3]*oneOverLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (normalizationOK) *normalizationOK = false;
|
||||
return Vector4<S>::ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set all components to 0
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline void Vector4<S>::setZero()
|
||||
{
|
||||
m_v[0] = 0;
|
||||
m_v[1] = 0;
|
||||
m_v[2] = 0;
|
||||
m_v[3] = 0;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Check if all components are zero (exact match)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline bool Vector4<S>::isZero() const
|
||||
{
|
||||
return (m_v[0] == 0) && (m_v[1] == 0) && (m_v[2] == 0) && (m_v[2] == 0);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set the components of the vector
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename S>
|
||||
inline void Vector4<S>::set(S x, S y, S z, S w)
|
||||
{
|
||||
m_v[0] = x;
|
||||
m_v[1] = y;
|
||||
m_v[2] = z;
|
||||
m_v[3] = w;
|
||||
}
|
||||
|
||||
} // namespace cvf
|
||||
@@ -0,0 +1,27 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
#define CVF_MAJOR_VERSION "0" // Major version number
|
||||
#define CVF_MINOR_VERSION "1" // Minor version number
|
||||
#define CVF_SPECIAL_BUILD "" // Special build description
|
||||
#define CVF_BUILD_NUMBER "2" // Build number. Increase for each shipment
|
||||
Reference in new issue
Block a user