mirror of https://github.com/mosra/magnum.git
108 changed files with 4420 additions and 354 deletions
|
After Width: | Height: | Size: 8.0 KiB |
@ -0,0 +1,202 @@
|
||||
/* |
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
namespace Magnum { |
||||
/** @page getting-started Getting started |
||||
@brief Get started with %Magnum in matter of minutes. |
||||
|
||||
@tableofcontents |
||||
|
||||
@section getting-started-download Download, build and install Magnum |
||||
|
||||
Get latest version from GitHub and install it. Read full guide on |
||||
@ref building "how to download, build and install Magnum" on platform of your |
||||
choice. For our first project we will use GLUT toolkit, don't forget to enable |
||||
it for building using `WITH_GLUTAPPLICATION` CMake parameter. |
||||
|
||||
@section getting-started-bootstrap Download bootstrap project |
||||
|
||||
Setting up a new project can be pretty gruesome and nobody likes repeating the |
||||
same process every time. %Magnum provides "bootstrap" project structures for |
||||
many use cases, helping you get up and running in no time. |
||||
|
||||
The [bootstrap repository](https://github.com/mosra/magnum-bootstrap) is |
||||
located on GitHub. The `master` branch contains just an README file and the |
||||
actual bootstrap projects are in various other branches, each covering some |
||||
particular use case. For your first project you would need the `base` branch, |
||||
which contains only the essential files you need. Download the branch [as an |
||||
archive](https://github.com/mosra/magnum-bootstrap/archive/base.zip) and |
||||
extract it somewhere. Do it rather than cloning the full repository, as it's |
||||
better to init your own repository from scratch to avoid having the history |
||||
polluted. |
||||
|
||||
@section getting-started-review Review project structure |
||||
|
||||
The base project consists of just seven files in two subfolders. %Magnum uses |
||||
CMake build system, see @ref cmake for more information. |
||||
|
||||
modules/FindCorrade.cmake |
||||
modules/FindMagnum.cmake |
||||
modules/FindGLEW.cmake |
||||
src/MyApplication.cpp |
||||
src/CMakeLists.txt |
||||
CMakeLists.txt |
||||
.gitignore |
||||
|
||||
In root there is pre-filled `.gitignore` for your Git project and also |
||||
project-wide `CMakeLists.txt`. It just sets up project name, specifies module |
||||
directory and delegates everything important to `CMakeLists.txt` in `src/` |
||||
subdirectory. |
||||
@code |
||||
cmake_minimum_required(VERSION 2.8.8) |
||||
project(MyApplication) |
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/modules/") |
||||
|
||||
add_subdirectory(src) |
||||
@endcode |
||||
|
||||
Directory `modules/` contains CMake modules for finding the needed |
||||
dependencies. Unlike modules for finding e.g. GLUT and OpenGL, which are part |
||||
of standard CMake installation, these aren't part of it and thus must be |
||||
distributed with the project. These files are just verbatim copied from %Magnum |
||||
repository. |
||||
|
||||
Directory `src/` contains the actual project. To keep things simple, the |
||||
project consists of just one source file with the most minimal code possible: |
||||
@code |
||||
#include <Platform/GlutApplication.h> |
||||
#include <DefaultFramebuffer.h> |
||||
|
||||
using namespace Magnum; |
||||
|
||||
class MyApplication: public Platform::Application { |
||||
public: |
||||
explicit MyApplication(const Arguments& arguments); |
||||
|
||||
protected: |
||||
void viewportEvent(const Vector2i& size) override; |
||||
void drawEvent() override; |
||||
}; |
||||
|
||||
MyApplication::MyApplication(const Arguments& arguments): Platform::Application(arguments) {} |
||||
|
||||
void MyApplication::viewportEvent(const Vector2i& size) { |
||||
defaultFramebuffer.setViewport({{}, size}); |
||||
} |
||||
|
||||
void MyApplication::drawEvent() { |
||||
defaultFramebuffer.clear(FramebufferClear::Color); |
||||
swapBuffers(); |
||||
} |
||||
|
||||
MAGNUM_APPLICATION_MAIN(MyApplication) |
||||
@endcode |
||||
|
||||
The application essentially does nothing, just clears properly sized screen |
||||
framebuffer to default (black) color and then does buffer swap to actually |
||||
display it on the screen. `CMakeLists.txt` finds %Magnum, sets up compiler |
||||
flags, creates the executable and links it to all needed libraries: |
||||
@code |
||||
find_package(Magnum REQUIRED GlutApplication) |
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CORRADE_CXX_FLAGS}") |
||||
include_directories(${MAGNUM_INCLUDE_DIRS} ${MAGNUM_APPLICATION_INCLUDE_DIRS}) |
||||
|
||||
add_executable(MyApplication MyApplication.cpp) |
||||
target_link_libraries(MyApplication |
||||
${MAGNUM_LIBRARIES} |
||||
${MAGNUM_APPLICATION_LIBRARIES}) |
||||
@endcode |
||||
|
||||
In the following tutorials the code will be explained more thoroughly. |
||||
|
||||
@section getting-started-build Build it and run |
||||
|
||||
In Linux (and other Unix-based OSs) you can build the example using the |
||||
following three commands: create out-of-source build directory, run cmake in it |
||||
and then run make. The application binary will then appear in src/ subdirectory |
||||
of build dir: |
||||
|
||||
mkdir -p build && cd build |
||||
cmake .. |
||||
make |
||||
./src/MyApplication |
||||
|
||||
On Windows, if you don't want to touch the command-line, the easiest way is to |
||||
open root `CMakeLists.txt` in QtCreator, let it import the project and then |
||||
just build and run the application. If CMake isn't able to find the |
||||
dependencies or the building fails for some reason, you might want to look at |
||||
@ref building-windows-troubleshooting. |
||||
|
||||
@image html getting-started.png |
||||
@image latex getting-started.png |
||||
|
||||
Now you can try to change something in the code. Without going too deep into |
||||
the concepts of graphics programming, we can change clear color to something |
||||
else and also print basic information about the GPU the engine is running on. |
||||
First include the needed headers: |
||||
@code |
||||
#include <Color.h> |
||||
#include <Context.h> |
||||
#include <Renderer.h> |
||||
@endcode |
||||
|
||||
And in the constructor (which is currently empty) change the clear color and |
||||
print something to debug output: |
||||
@code |
||||
Renderer::setClearColor({0.07f, 0.44f, 0.73f}); |
||||
|
||||
Debug() << "Hello! This application is running on" << Context::current()->version() |
||||
<< "using" << Context::current()->rendererString(); |
||||
@endcode |
||||
|
||||
After rebuilding and starting the application, the clear color changes to |
||||
blueish one and something like this would be printed to the console: |
||||
@code |
||||
Hello! This application is running on OpenGL 3.3 using Geforce GT 330M |
||||
@endcode |
||||
|
||||
@image html getting-started-blue.png |
||||
@image latex getting-started-blue.png |
||||
|
||||
@section getting-started-tutorials Follow tutorials and learn the principles |
||||
|
||||
Now that you have your first application up and running, the best way to |
||||
continue is to render your first triangle in @ref example-index "step-by-step tutorial". |
||||
Then you can dig deeper and try other examples, read about |
||||
@ref features "fundamental principles" in the documentation and start |
||||
experimenting on your own! |
||||
|
||||
@section getting-started-more Additional information |
||||
|
||||
- @subpage building |
||||
- @subpage building-plugins |
||||
- @subpage building-integration |
||||
- @subpage cmake |
||||
- @subpage cmake-plugins |
||||
- @subpage cmake-integration |
||||
|
||||
*/ |
||||
} |
||||
|
After Width: | Height: | Size: 8.0 KiB |
@ -0,0 +1,97 @@
|
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#include "AbstractImporter.h" |
||||
|
||||
#include <fstream> |
||||
#include <Containers/Array.h> |
||||
#include <Utility/Assert.h> |
||||
|
||||
namespace Magnum { namespace Audio { |
||||
|
||||
AbstractImporter::AbstractImporter() = default; |
||||
|
||||
AbstractImporter::AbstractImporter(PluginManager::AbstractManager* manager, std::string plugin): PluginManager::AbstractPlugin(manager, std::move(plugin)) {} |
||||
|
||||
bool AbstractImporter::openData(Containers::ArrayReference<const unsigned char> data) { |
||||
CORRADE_ASSERT(features() & Feature::OpenData, |
||||
"Audio::AbstractImporter::openData(): feature not supported", nullptr); |
||||
|
||||
close(); |
||||
doOpenData(data); |
||||
return isOpened(); |
||||
} |
||||
|
||||
void AbstractImporter::doOpenData(Containers::ArrayReference<const unsigned char>) { |
||||
CORRADE_ASSERT(false, "Audio::AbstractImporter::openData(): feature advertised but not implemented", ); |
||||
} |
||||
|
||||
bool AbstractImporter::openFile(const std::string& filename) { |
||||
close(); |
||||
doOpenFile(filename); |
||||
return isOpened(); |
||||
} |
||||
|
||||
void AbstractImporter::doOpenFile(const std::string& filename) { |
||||
CORRADE_ASSERT(features() & Feature::OpenData, "Audio::AbstractImporter::openFile(): not implemented", ); |
||||
|
||||
/* Open file */ |
||||
std::ifstream in(filename.data(), std::ios::binary); |
||||
if(!in.good()) { |
||||
Error() << "Trade::AbstractImporter::openFile(): cannot open file" << filename; |
||||
return; |
||||
} |
||||
|
||||
/* Create array to hold file contents */ |
||||
in.seekg(0, std::ios::end); |
||||
Containers::Array<unsigned char> data(in.tellg()); |
||||
|
||||
/* Read data, close */ |
||||
in.seekg(0, std::ios::beg); |
||||
in.read(reinterpret_cast<char*>(data.begin()), data.size()); |
||||
in.close(); |
||||
|
||||
doOpenData(data); |
||||
} |
||||
|
||||
void AbstractImporter::close() { |
||||
if(isOpened()) doClose(); |
||||
} |
||||
|
||||
Buffer::Format AbstractImporter::format() const { |
||||
CORRADE_ASSERT(isOpened(), "Audio::AbstractImporter::format(): no file opened", {}); |
||||
return doFormat(); |
||||
} |
||||
|
||||
UnsignedInt AbstractImporter::frequency() const { |
||||
CORRADE_ASSERT(isOpened(), "Audio::AbstractImporter::frequency(): no file opened", {}); |
||||
return doFrequency(); |
||||
} |
||||
|
||||
Containers::Array<unsigned char> AbstractImporter::data() { |
||||
CORRADE_ASSERT(isOpened(), "Audio::AbstractImporter::data(): no file opened", {}); |
||||
return doData(); |
||||
} |
||||
|
||||
}} |
||||
@ -0,0 +1,163 @@
|
||||
#ifndef Magnum_Audio_AbstractImporter_h |
||||
#define Magnum_Audio_AbstractImporter_h |
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
/** @file Audio/AbstractImporter.h
|
||||
* @brief Class Magnum::Audio::AbstractImporter |
||||
*/ |
||||
|
||||
#include <PluginManager/AbstractPlugin.h> |
||||
|
||||
#include "Magnum.h" |
||||
#include "Audio/Buffer.h" |
||||
|
||||
namespace Magnum { namespace Audio { |
||||
|
||||
/**
|
||||
@brief Base for audio importer plugins |
||||
|
||||
@section Audio-AbstractImporter-subclassing Subclassing |
||||
|
||||
Plugin implements function doFeatures(), doIsOpened(), one of or both |
||||
doOpenData() and doOpenFile() functions, function doClose() and data access |
||||
functions doFormat(), doFrequency() and doData(). |
||||
|
||||
You don't need to do most of the redundant sanity checks, these things are |
||||
checked by the implementation: |
||||
|
||||
- Functions doOpenData() and doOpenFile() are called after the previous file |
||||
was closed, function doClose() is called only if there is any file opened. |
||||
- Function doOpenData() is called only if @ref Feature "Feature::OpenData" |
||||
is supported. |
||||
- All `do*()` implementations working on opened file are called only if |
||||
there is any file opened. |
||||
*/ |
||||
class MAGNUM_AUDIO_EXPORT AbstractImporter: public PluginManager::AbstractPlugin { |
||||
CORRADE_PLUGIN_INTERFACE("cz.mosra.magnum.Audio.AbstractImporter/0.1") |
||||
|
||||
public: |
||||
/**
|
||||
* @brief Features supported by this importer |
||||
* |
||||
* @see Features, features() |
||||
*/ |
||||
enum class Feature: UnsignedByte { |
||||
/** Opening files from raw data using openData() */ |
||||
OpenData = 1 << 0 |
||||
}; |
||||
|
||||
/**
|
||||
* @brief Features supported by this importer |
||||
* |
||||
* @see features() |
||||
*/ |
||||
typedef Containers::EnumSet<Feature, UnsignedByte> Features; |
||||
|
||||
/** @brief Default constructor */ |
||||
explicit AbstractImporter(); |
||||
|
||||
/** @brief Plugin manager constructor */ |
||||
explicit AbstractImporter(PluginManager::AbstractManager* manager, std::string plugin); |
||||
|
||||
/** @brief Features supported by this importer */ |
||||
Features features() const { return doFeatures(); } |
||||
|
||||
/** @brief Whether any file is opened */ |
||||
bool isOpened() const { return doIsOpened(); } |
||||
|
||||
/**
|
||||
* @brief Open raw data |
||||
* |
||||
* Closes previous file, if it was opened, and tries to open given |
||||
* file. Available only if @ref Feature "Feature::OpenData" is |
||||
* supported. Returns `true` on success, `false` otherwise. |
||||
* @see features(), openFile() |
||||
*/ |
||||
bool openData(Containers::ArrayReference<const unsigned char> data); |
||||
|
||||
/**
|
||||
* @brief Open file |
||||
* |
||||
* Closes previous file, if it was opened, and tries to open given |
||||
* file. Returns `true` on success, `false` otherwise. |
||||
* @see features(), openData() |
||||
*/ |
||||
bool openFile(const std::string& filename); |
||||
|
||||
/** @brief Close file */ |
||||
void close(); |
||||
|
||||
/** @{ @name Data access */ |
||||
|
||||
/** @brief Sample format */ |
||||
Buffer::Format format() const; |
||||
|
||||
/** @brief Sample frequency */ |
||||
UnsignedInt frequency() const; |
||||
|
||||
/** @brief Sample data */ |
||||
Containers::Array<unsigned char> data(); |
||||
|
||||
/*@}*/ |
||||
|
||||
#ifndef DOXYGEN_GENERATING_OUTPUT |
||||
private: |
||||
#else |
||||
protected: |
||||
#endif |
||||
/** @brief Implementation for features() */ |
||||
virtual Features doFeatures() const = 0; |
||||
|
||||
/** @brief Implementation for isOpened() */ |
||||
virtual bool doIsOpened() const = 0; |
||||
|
||||
/** @brief Implementation for openData() */ |
||||
virtual void doOpenData(Containers::ArrayReference<const unsigned char> data); |
||||
|
||||
/**
|
||||
* @brief Implementation for openFile() |
||||
* |
||||
* If @ref Feature "Feature::OpenData" is supported, default |
||||
* implementation opens the file and calls doOpenData() with its |
||||
* contents. |
||||
*/ |
||||
virtual void doOpenFile(const std::string& filename); |
||||
|
||||
/** @brief Implementation for close() */ |
||||
virtual void doClose() = 0; |
||||
|
||||
/** @brief Implementation for format() */ |
||||
virtual Buffer::Format doFormat() const = 0; |
||||
|
||||
/** @brief Implementation for frequency() */ |
||||
virtual UnsignedInt doFrequency() const = 0; |
||||
|
||||
/** @brief Implementation for data() */ |
||||
virtual Containers::Array<unsigned char> doData() = 0; |
||||
}; |
||||
|
||||
}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,49 @@
|
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#include <type_traits> |
||||
#include <al.h> |
||||
|
||||
#include "Types.h" |
||||
|
||||
namespace Magnum { namespace Audio { |
||||
|
||||
/* Verify types */ |
||||
static_assert(std::is_same<ALubyte, UnsignedByte>::value, "ALubyte is not the same as UnsignedByte"); |
||||
static_assert(std::is_same<ALbyte, Byte>::value, "ALbyte is not the same as Byte"); |
||||
static_assert(std::is_same<ALushort, UnsignedShort>::value, "ALushort is not the same as UnsignedShort"); |
||||
static_assert(std::is_same<ALshort, Short>::value, "ALshort is not the same as Short"); |
||||
static_assert(std::is_same<ALuint, UnsignedInt>::value, "ALuint is not the same as UnsignedInt"); |
||||
static_assert(std::is_same<ALint, Int>::value, "ALint is not the same as Int"); |
||||
static_assert(std::is_same<ALsizei, Int>::value, "ALsizei is not the same as Int"); |
||||
static_assert(std::is_same<ALfloat, Float>::value, "ALfloat is not the same as Float"); |
||||
#ifndef MAGNUM_TARGET_GLES |
||||
static_assert(std::is_same<ALdouble, Double>::value, "ALdouble is not the same as Double"); |
||||
#endif |
||||
|
||||
/* Verify boolean values */ |
||||
static_assert(AL_FALSE == false, "AL_FALSE is not the same as false"); |
||||
static_assert(AL_TRUE == true, "AL_TRUE is not the same as true"); |
||||
|
||||
}} |
||||
@ -0,0 +1,41 @@
|
||||
#ifndef Magnum_Audio_Audio_h |
||||
#define Magnum_Audio_Audio_h |
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
/** @file
|
||||
* @brief Forward declarations for Magnum::Audio namespace |
||||
*/ |
||||
|
||||
namespace Magnum { namespace Audio { |
||||
|
||||
class AbstractImporter; |
||||
class Buffer; |
||||
class Context; |
||||
class Source; |
||||
/* Renderer used only statically */ |
||||
|
||||
}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,44 @@
|
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#include "Buffer.h" |
||||
|
||||
#include <Utility/Debug.h> |
||||
|
||||
namespace Magnum { namespace Audio { |
||||
|
||||
Debug operator<<(Debug debug, const Buffer::Format value) { |
||||
switch(value) { |
||||
#define _c(value) case Buffer::Format::value: return debug << "Audio::Buffer::Format::" #value; |
||||
_c(Mono8) |
||||
_c(Mono16) |
||||
_c(Stereo8) |
||||
_c(Stereo16) |
||||
#undef _c |
||||
} |
||||
|
||||
return debug << "Audio::Buffer::Format::(invalid)"; |
||||
} |
||||
|
||||
}} |
||||
@ -0,0 +1,120 @@
|
||||
#ifndef Magnum_Audio_Buffer_h |
||||
#define Magnum_Audio_Buffer_h |
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
/** @file
|
||||
* @brief Class Magnum::Audio::Buffer |
||||
*/ |
||||
|
||||
#include <utility> |
||||
#include <al.h> |
||||
#include <Containers/Array.h> |
||||
|
||||
#include "Magnum.h" |
||||
#include "Audio/magnumAudioVisibility.h" |
||||
|
||||
namespace Magnum { namespace Audio { |
||||
|
||||
/** @brief Sample buffer */ |
||||
class Buffer { |
||||
public: |
||||
/**
|
||||
* @brief Sample format |
||||
* |
||||
* @note Multi-channel format is played without 3D spatialization |
||||
* (useful for background music) |
||||
* @see @ref setData() |
||||
*/ |
||||
enum class Format: ALenum { |
||||
Mono8 = AL_FORMAT_MONO8, /**< 8-bit unsigned mono */ |
||||
Mono16 = AL_FORMAT_MONO16, /**< 16-bit signed mono */ |
||||
Stereo8 = AL_FORMAT_STEREO8, /**< 8-bit interleaved unsigned stereo */ |
||||
Stereo16 = AL_FORMAT_STEREO16 /**< 16-bit interleaved signed stereo */ |
||||
}; |
||||
|
||||
/**
|
||||
* @brief Constructor |
||||
* |
||||
* Creates OpenAL buffer object. |
||||
* @see @fn_al{GenBuffers} |
||||
*/ |
||||
explicit Buffer() { alGenBuffers(1, &_id); } |
||||
|
||||
/**
|
||||
* @brief Destructor |
||||
* |
||||
* Deletes OpenAL buffer object. |
||||
* @see @fn_al{DeleteBuffers} |
||||
*/ |
||||
~Buffer() { if(_id) alDeleteBuffers(1, &_id); } |
||||
|
||||
/** @brief Copying is not allowed */ |
||||
Buffer(const Buffer&) = delete; |
||||
|
||||
/** @brief Move constructor */ |
||||
Buffer(Buffer&& other); |
||||
|
||||
/** @brief Copying is not allowed */ |
||||
Buffer& operator=(const Buffer&) = delete; |
||||
|
||||
/** @brief Move assignment */ |
||||
Buffer& operator=(Buffer&& other); |
||||
|
||||
/** @brief OpenAL buffer ID */ |
||||
ALuint id() const { return _id; } |
||||
|
||||
/**
|
||||
* @brief Set buffer data |
||||
* @param format Sample format |
||||
* @param data Data |
||||
* @param frequency Frequency |
||||
* @return Reference to self (for method chaining) |
||||
* |
||||
* @see @fn_al{BufferData} |
||||
*/ |
||||
Buffer& setData(Format format, Containers::ArrayReference<const void> data, ALsizei frequency) { |
||||
alBufferData(_id, ALenum(format), data, data.size(), frequency); |
||||
return *this; |
||||
} |
||||
|
||||
private: |
||||
ALuint _id; |
||||
}; |
||||
|
||||
/** @debugoperator{Magnum::Audio::Buffer} */ |
||||
Debug MAGNUM_AUDIO_EXPORT operator<<(Debug debug, Buffer::Format value); |
||||
|
||||
inline Buffer::Buffer(Buffer&& other): _id(other._id) { |
||||
other._id = 0; |
||||
} |
||||
|
||||
inline Buffer& Buffer::operator=(Buffer&& other) { |
||||
std::swap(_id, other._id); |
||||
return *this; |
||||
} |
||||
|
||||
}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,55 @@
|
||||
# |
||||
# This file is part of Magnum. |
||||
# |
||||
# Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
# |
||||
# Permission is hereby granted, free of charge, to any person obtaining a |
||||
# copy of this software and associated documentation files (the "Software"), |
||||
# to deal in the Software without restriction, including without limitation |
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
# and/or sell copies of the Software, and to permit persons to whom the |
||||
# Software is furnished to do so, subject to the following conditions: |
||||
# |
||||
# The above copyright notice and this permission notice shall be included |
||||
# in all copies or substantial portions of the Software. |
||||
# |
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
# DEALINGS IN THE SOFTWARE. |
||||
# |
||||
|
||||
find_package(OpenAL REQUIRED) |
||||
|
||||
include_directories(${OPENAL_INCLUDE_DIR}) |
||||
|
||||
set(MagnumAudio_SOURCES |
||||
AbstractImporter.cpp |
||||
Audio.cpp |
||||
Buffer.cpp |
||||
Context.cpp |
||||
Renderer.cpp |
||||
Source.cpp) |
||||
|
||||
set(MagnumAudio_HEADERS |
||||
AbstractImporter.h |
||||
Audio.h |
||||
Buffer.h |
||||
Context.h |
||||
Renderer.h |
||||
Source.h |
||||
|
||||
magnumAudioVisibility.h) |
||||
|
||||
add_library(MagnumAudio ${SHARED_OR_STATIC} ${MagnumAudio_SOURCES}) |
||||
target_link_libraries(MagnumAudio ${CORRADE_PLUGINMANAGER_LIBRARIES} ${OPENAL_LIBRARY}) |
||||
|
||||
install(TARGETS MagnumAudio DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) |
||||
install(FILES ${MagnumAudio_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Audio) |
||||
|
||||
if(BUILD_TESTS) |
||||
add_subdirectory(Test) |
||||
endif() |
||||
@ -0,0 +1,65 @@
|
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#include "Context.h" |
||||
|
||||
#include <alc.h> |
||||
#include <Utility/Assert.h> |
||||
#include <Utility/Debug.h> |
||||
|
||||
#include "Magnum.h" |
||||
|
||||
namespace Magnum { namespace Audio { |
||||
|
||||
Context* Context::_current = nullptr; |
||||
|
||||
Context::Context() { |
||||
CORRADE_ASSERT(!_current, "Audio::Context: context already created", ); |
||||
|
||||
/* Open default device */ |
||||
const ALCchar* const defaultDevice = alcGetString(nullptr, ALC_DEFAULT_DEVICE_SPECIFIER); |
||||
_device = alcOpenDevice(defaultDevice); |
||||
if(!_device) { |
||||
Error() << "Audio::Context: cannot open sound device" << defaultDevice; |
||||
std::exit(1); |
||||
} |
||||
|
||||
_context = alcCreateContext(_device, nullptr); |
||||
if(!_context) { |
||||
Error() << "Audio::Context: cannot create context:" << alcGetError(_device); |
||||
std::exit(1); |
||||
} |
||||
|
||||
alcMakeContextCurrent(_context); |
||||
_current = this; |
||||
} |
||||
|
||||
Context::~Context() { |
||||
CORRADE_INTERNAL_ASSERT(_current == this); |
||||
|
||||
alcDestroyContext(_context); |
||||
alcCloseDevice(_device); |
||||
} |
||||
|
||||
}} |
||||
@ -0,0 +1,95 @@
|
||||
#ifndef Magnum_Audio_Context_h |
||||
#define Magnum_Audio_Context_h |
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
/** @file
|
||||
* @brief Class Magnum::Audio::Context |
||||
*/ |
||||
|
||||
#include <al.h> |
||||
#include <string> |
||||
|
||||
#include "Audio/magnumAudioVisibility.h" |
||||
|
||||
#ifndef DOXYGEN_GENERATING_OUTPUT |
||||
typedef struct ALCdevice_struct ALCdevice; |
||||
typedef struct ALCcontext_struct ALCcontext; |
||||
#endif |
||||
|
||||
namespace Magnum { namespace Audio { |
||||
|
||||
/**
|
||||
@brief OpenAL context |
||||
*/ |
||||
class MAGNUM_AUDIO_EXPORT Context { |
||||
public: |
||||
/** @brief Current context */ |
||||
static Context* current() { return _current; } |
||||
|
||||
/**
|
||||
* @brief Constructor |
||||
* |
||||
* Creates OpenAL context. |
||||
*/ |
||||
explicit Context(); |
||||
|
||||
/**
|
||||
* @brief Destructor |
||||
* |
||||
* Destroys OpenAL context. |
||||
*/ |
||||
~Context(); |
||||
|
||||
/**
|
||||
* @brief Vendor string |
||||
* |
||||
* @see rendererString(), @fn_al{GetString} with @def_al{VENDOR} |
||||
*/ |
||||
std::string vendorString() const { return alGetString(AL_VENDOR); } |
||||
|
||||
/**
|
||||
* @brief %Renderer string |
||||
* |
||||
* @see vendorString(), @fn_al{GetString} with @def_al{RENDERER} |
||||
*/ |
||||
std::string rendererString() const { return alGetString(AL_RENDERER); } |
||||
|
||||
/**
|
||||
* @brief Version string |
||||
* |
||||
* @see @fn_al{GetString} with @def_al{VERSION} |
||||
*/ |
||||
std::string versionString() const { return alGetString(AL_VERSION); } |
||||
|
||||
private: |
||||
static Context* _current; |
||||
|
||||
ALCdevice* _device; |
||||
ALCcontext* _context; |
||||
}; |
||||
|
||||
}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,46 @@
|
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#include "Renderer.h" |
||||
|
||||
#include <Utility/Debug.h> |
||||
|
||||
namespace Magnum { namespace Audio { |
||||
|
||||
Debug operator<<(Debug debug, const Renderer::Error value) { |
||||
switch(value) { |
||||
#define _c(value) case Renderer::Error::value: return debug << "Audio::Renderer::Error::" #value; |
||||
_c(NoError) |
||||
_c(InvalidName) |
||||
_c(InvalidEnum) |
||||
_c(InvalidValue) |
||||
_c(InvalidOperation) |
||||
_c(OutOfMemory) |
||||
#undef _c |
||||
} |
||||
|
||||
return debug << "Audio::Renderer::Error::(invalid)"; |
||||
} |
||||
|
||||
}} |
||||
@ -0,0 +1,202 @@
|
||||
#ifndef Magnum_Audio_Renderer_h |
||||
#define Magnum_Audio_Renderer_h |
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
/** @file
|
||||
* @brief Class Magnum::Audio::Renderer |
||||
*/ |
||||
|
||||
#include <al.h> |
||||
|
||||
#include "Math/Vector3.h" |
||||
#include "Magnum.h" |
||||
#include "Audio/magnumAudioVisibility.h" |
||||
|
||||
namespace Magnum { namespace Audio { |
||||
|
||||
/** @brief Global renderer configuration */ |
||||
class Renderer { |
||||
public: |
||||
Renderer() = delete; |
||||
|
||||
/**
|
||||
* @brief Error status |
||||
* |
||||
* @see error() |
||||
*/ |
||||
enum class Error: ALenum { |
||||
NoError = AL_NO_ERROR, /**< No error occured */ |
||||
InvalidName = AL_INVALID_NAME, /**< Invalid name parameter */ |
||||
InvalidEnum = AL_INVALID_ENUM, /**< Invalid enum parameter */ |
||||
InvalidValue = AL_INVALID_VALUE, /**< Invalid enum value parameter */ |
||||
InvalidOperation = AL_INVALID_OPERATION, /**< Illegal call */ |
||||
OutOfMemory = AL_OUT_OF_MEMORY /**< Unable to allocate memory */ |
||||
}; |
||||
|
||||
/** @brief Error status */ |
||||
static Error error() { return Error(alGetError()); } |
||||
|
||||
/** @{ @name Listener positioning */ |
||||
|
||||
/**
|
||||
* @brief Set listener position |
||||
* |
||||
* Default is `{0.0f, 0.0f, 0.0f}`. |
||||
* @see @fn_al{Listenerfv} with @def_al{POSITION} |
||||
*/ |
||||
static void setListenerPosition(const Vector3& position) { |
||||
alListenerfv(AL_POSITION, position.data()); |
||||
} |
||||
|
||||
/** @overload
|
||||
* @see @fn_al{Listeneriv} with @def_al{POSITION} |
||||
*/ |
||||
static void setListenerPosition(const Vector3i& position) { |
||||
alListeneriv(AL_POSITION, position.data()); |
||||
} |
||||
|
||||
/**
|
||||
* @brief Set listener orientation |
||||
* |
||||
* The values must be linearly independent and don't need to be |
||||
* normalized. Default is -Z and +Y. |
||||
* @see @fn_al{Listenerfv} with @def_al{ORIENTATION} |
||||
*/ |
||||
static void setListenerOrientation(const Vector3& forward, const Vector3& up); |
||||
|
||||
/** @overload
|
||||
* @see @fn_al{Listeneriv} with @def_al{ORIENTATION} |
||||
*/ |
||||
static void setListenerOrientation(const Vector3i& forward, const Vector3i& up); |
||||
|
||||
/**
|
||||
* @brief Set listener velocity |
||||
* |
||||
* Default is `{0.0f, 0.0f, 0.0f}`. |
||||
* @see @fn_al{Listenerfv} with @def_al{VELOCITY} |
||||
*/ |
||||
static void setListenerVelocity(const Vector3& velocity) { |
||||
alListenerfv(AL_VELOCITY, velocity.data()); |
||||
} |
||||
|
||||
/** @overload
|
||||
* @see @fn_al{Listeneriv} with @def_al{VELOCITY} |
||||
*/ |
||||
static void setListenerVelocity(const Vector3i& velocity) { |
||||
alListeneriv(AL_VELOCITY, velocity.data()); |
||||
} |
||||
|
||||
/*@}*/ |
||||
|
||||
/** @{ @name Global behavior */ |
||||
|
||||
/**
|
||||
* @brief Distance model |
||||
* |
||||
* @see setDistanceModel() |
||||
*/ |
||||
enum class DistanceModel: ALenum { |
||||
/** No distance attenuation calculation */ |
||||
None = AL_NONE, |
||||
|
||||
/** Inverse distance */ |
||||
Inverse = AL_INVERSE_DISTANCE, |
||||
|
||||
/** Inverse distance, clamped */ |
||||
InverseClamped = AL_INVERSE_DISTANCE_CLAMPED, |
||||
|
||||
/** Linear distance */ |
||||
Linear = AL_LINEAR_DISTANCE, |
||||
|
||||
/** Linear distance, clamped */ |
||||
LinearClamped = AL_LINEAR_DISTANCE_CLAMPED, |
||||
|
||||
/** Exponential distance */ |
||||
Exponent = AL_EXPONENT_DISTANCE, |
||||
|
||||
/** Exponential distance, clamped */ |
||||
ExponentClamped = AL_EXPONENT_DISTANCE_CLAMPED |
||||
}; |
||||
|
||||
/**
|
||||
* @brief Set listener gain |
||||
* |
||||
* Default is `1.0f`, which means that the sound is unattenuated. |
||||
* If set to `0.0f`, all sound is muted. |
||||
* @see @fn_al{Listenerf} with @def_al{GAIN} |
||||
*/ |
||||
static void setListenerGain(Float gain) { |
||||
alListenerf(AL_GAIN, gain); |
||||
} |
||||
|
||||
/**
|
||||
* @brief Set Doppler factor |
||||
* |
||||
* Default is `1.0f`. If set to `0.0f`, the effect is disabled. |
||||
* @see @ref setSpeedOfSound(), @fn_al{DopplerFactor} |
||||
*/ |
||||
static void setDopplerFactor(Float factor) { |
||||
alDopplerFactor(factor); |
||||
} |
||||
|
||||
/**
|
||||
* @brief Set speed of sound |
||||
* |
||||
* Default is `343.3f` (meters per second). |
||||
* @see @ref setDopplerFactor(), @fn_al{SpeedOfSound} |
||||
*/ |
||||
static void setSpeedOfSound(Float speed) { |
||||
alSpeedOfSound(speed); |
||||
} |
||||
|
||||
/**
|
||||
* @brief Set distance model |
||||
* |
||||
* Default is @ref DistanceModel "DistanceModel::InverseClamped". |
||||
* @see @fn_al{DistanceModel} |
||||
*/ |
||||
static void setDistanceModel(DistanceModel model) { |
||||
alDistanceModel(ALenum(model)); |
||||
} |
||||
|
||||
/*@}*/ |
||||
}; |
||||
|
||||
/** @debugoperator{Magnum::Audio::Renderer} */ |
||||
Debug MAGNUM_AUDIO_EXPORT operator<<(Debug debug, Renderer::Error value); |
||||
|
||||
inline void Renderer::setListenerOrientation(const Vector3& forward, const Vector3& up) { |
||||
const Vector3 data[] = {forward, up}; |
||||
alListenerfv(AL_ORIENTATION, data[0].data()); |
||||
} |
||||
|
||||
inline void Renderer::setListenerOrientation(const Vector3i& forward, const Vector3i& up) { |
||||
const Vector3i data[] = {forward, up}; |
||||
alListeneriv(AL_ORIENTATION, data[0].data()); |
||||
} |
||||
|
||||
}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,123 @@
|
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#include "Source.h" |
||||
|
||||
#include "Audio/Buffer.h" |
||||
|
||||
namespace Magnum { namespace Audio { |
||||
|
||||
/** @todo C++14: use VLA to avoid unnecessary allocations */ |
||||
|
||||
Source& Source::setBuffer(Buffer* buffer) { |
||||
alSourcei(_id, AL_BUFFER, buffer ? buffer->id() : 0); |
||||
return *this; |
||||
} |
||||
|
||||
namespace { |
||||
|
||||
const ALuint* sourceIds(const std::initializer_list<Source*>& sources) { |
||||
ALuint* const ids = new ALuint[sources.size()]; |
||||
for(auto it = sources.begin(); it != sources.end(); ++it) { |
||||
CORRADE_INTERNAL_ASSERT(*it); |
||||
ids[it-sources.begin()] = (*it)->id(); |
||||
} |
||||
return ids; |
||||
} |
||||
|
||||
const ALuint* sourceIds(const std::vector<Source*>& sources) { |
||||
ALuint* const ids = new ALuint[sources.size()]; |
||||
for(auto it = sources.begin(); it != sources.end(); ++it) { |
||||
CORRADE_INTERNAL_ASSERT(*it); |
||||
ids[it-sources.begin()] = (*it)->id(); |
||||
} |
||||
return ids; |
||||
} |
||||
|
||||
} |
||||
|
||||
/** @todo Okay, this is too much code copying even for me */ |
||||
|
||||
void Source::play(std::initializer_list<Source*> sources) { |
||||
const ALuint* const ids = sourceIds(sources); |
||||
alSourcePlayv(sources.size(), ids); |
||||
delete[] ids; |
||||
} |
||||
|
||||
void Source::play(const std::vector<Source*>& sources) { |
||||
const ALuint* const ids = sourceIds(sources); |
||||
alSourcePlayv(sources.size(), ids); |
||||
delete[] ids; |
||||
} |
||||
|
||||
void Source::pause(std::initializer_list<Source*> sources) { |
||||
const ALuint* const ids = sourceIds(sources); |
||||
alSourcePausev(sources.size(), ids); |
||||
delete[] ids; |
||||
} |
||||
|
||||
void Source::pause(const std::vector<Source*>& sources) { |
||||
const ALuint* const ids = sourceIds(sources); |
||||
alSourcePausev(sources.size(), ids); |
||||
delete[] ids; |
||||
} |
||||
|
||||
void Source::stop(std::initializer_list<Source*> sources) { |
||||
const ALuint* const ids = sourceIds(sources); |
||||
alSourceStopv(sources.size(), ids); |
||||
delete[] ids; |
||||
} |
||||
|
||||
void Source::stop(const std::vector<Source*>& sources) { |
||||
const ALuint* const ids = sourceIds(sources); |
||||
alSourceStopv(sources.size(), ids); |
||||
delete[] ids; |
||||
} |
||||
|
||||
void Source::rewind(std::initializer_list<Source*> sources) { |
||||
const ALuint* const ids = sourceIds(sources); |
||||
alSourceRewindv(sources.size(), ids); |
||||
delete[] ids; |
||||
} |
||||
|
||||
void Source::rewind(const std::vector<Source*>& sources) { |
||||
const ALuint* const ids = sourceIds(sources); |
||||
alSourceRewindv(sources.size(), ids); |
||||
delete[] ids; |
||||
} |
||||
|
||||
Debug operator<<(Debug debug, const Source::State value) { |
||||
switch(value) { |
||||
#define _c(value) case Source::State::value: return debug << "Audio::Source::State::" #value; |
||||
_c(Initial) |
||||
_c(Playing) |
||||
_c(Paused) |
||||
_c(Stopped) |
||||
#undef _c |
||||
} |
||||
|
||||
return debug << "Audio::Source::State::(invalid)"; |
||||
} |
||||
|
||||
}} |
||||
@ -0,0 +1,596 @@
|
||||
#ifndef Magnum_Audio_Source_h |
||||
#define Magnum_Audio_Source_h |
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
/** @file
|
||||
* @brief Class Magnum::Audio::Source |
||||
*/ |
||||
|
||||
#include <initializer_list> |
||||
#include <vector> |
||||
#include <al.h> |
||||
|
||||
#include "Math/Vector3.h" |
||||
#include "Magnum.h" |
||||
#include "Audio/Audio.h" |
||||
#include "Audio/magnumAudioVisibility.h" |
||||
|
||||
namespace Magnum { namespace Audio { |
||||
|
||||
/**
|
||||
@brief %Source |
||||
|
||||
Manages positional audio source. |
||||
@todo Expose convenient API for buffer queuing |
||||
*/ |
||||
class MAGNUM_AUDIO_EXPORT Source { |
||||
public: |
||||
/**
|
||||
* @brief Constructor |
||||
* |
||||
* Creates OpenAL source object. |
||||
* @see @fn_al{GenSources} |
||||
*/ |
||||
explicit Source() { alGenSources(1, &_id); } |
||||
|
||||
/**
|
||||
* @brief Destructor |
||||
* |
||||
* Deletes OpenAL source object. |
||||
* @see @fn_al{DeleteSources} |
||||
*/ |
||||
~Source() { if(_id) alDeleteSources(1, &_id); } |
||||
|
||||
/** @brief Copying is not allowed */ |
||||
Source(const Source&) = delete; |
||||
|
||||
/** @brief Move constructor */ |
||||
Source(Source&& other); |
||||
|
||||
/** @brief Copying is not allowed */ |
||||
Source& operator=(const Source&) = delete; |
||||
|
||||
/** @brief Move assignment */ |
||||
Source& operator=(Source&& other); |
||||
|
||||
/** @brief OpenAL source ID */ |
||||
ALuint id() const { return _id; } |
||||
|
||||
/** @{ @name Source positioning */ |
||||
|
||||
/**
|
||||
* @brief Set position |
||||
* @return Reference to self (for method chaining) |
||||
* |
||||
* Default is `{0.0f, 0.0f, 0.0f}`. |
||||
* @see @ref setRelative(), @fn_al{Sourcefv} with @def_al{POSITION} |
||||
*/ |
||||
Source& setPosition(const Vector3& position) { |
||||
alSourcefv(_id, AL_POSITION, position.data()); |
||||
return *this; |
||||
} |
||||
|
||||
/** @overload
|
||||
* @see @fn_al{Sourceiv} with @def_al{POSITION} |
||||
*/ |
||||
Source& setPosition(const Vector3i& position) { |
||||
alSourceiv(_id, AL_POSITION, position.data()); |
||||
return *this; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Set velocity |
||||
* @return Reference to self (for method chaining) |
||||
* |
||||
* Default is `{0.0f, 0.0f, 0.0f}`. |
||||
* @see @ref setRelative(), @fn_al{Sourcefv} with @def_al{VELOCITY} |
||||
*/ |
||||
Source& setVelocity(const Vector3& velocity) { |
||||
alSourcefv(_id, AL_VELOCITY, velocity.data()); |
||||
return *this; |
||||
} |
||||
|
||||
/** @overload
|
||||
* @see @fn_al{Sourceiv} with @def_al{VELOCITY} |
||||
*/ |
||||
Source& setVelocity(const Vector3i& velocity) { |
||||
alSourceiv(_id, AL_VELOCITY, velocity.data()); |
||||
return *this; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Interpret source relatively to listener |
||||
* |
||||
* When enabled, source position, direction and velocity will be |
||||
* interpreted relatively to listener. Default is `false`. |
||||
* @see @ref setPosition(), @ref setDirection(), @ref setVelocity(), |
||||
* @fn_al{Sourcei} with @def_al{SOURCE_RELATIVE} |
||||
*/ |
||||
Source& setRelative(bool relative) { |
||||
alSourcei(_id, AL_SOURCE_RELATIVE, relative); |
||||
return *this; |
||||
} |
||||
|
||||
/*@}*/ |
||||
|
||||
/** @{ @name Source behavior */ |
||||
|
||||
/**
|
||||
* @brief Set gain |
||||
* @return Reference to self (for method chaining) |
||||
* |
||||
* Default is `1.0f`, which means that the sound is unattenuated. |
||||
* If set to `0.0f`, the source is muted. |
||||
* @see @ref setMinGain(), @ref setMaxGain(), @fn_al{Sourcef} with |
||||
* @def_al{GAIN} |
||||
*/ |
||||
Source& setGain(Float gain) { |
||||
alSourcef(_id, AL_GAIN, gain); |
||||
return *this; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Set min gain |
||||
* @return Reference to self (for method chaining) |
||||
* |
||||
* If effective gain is lower than min gain, min gain is used. Note |
||||
* that this is done before listener gain is applied. Default is |
||||
* `0.0f`. |
||||
* @see @ref setMinGain(), @ref setGain(), @fn_al{Sourcef} with |
||||
* @def_al{MIN_GAIN} |
||||
*/ |
||||
Source& setMinGain(Float gain) { |
||||
alSourcef(_id, AL_MIN_GAIN, gain); |
||||
return *this; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Set max gain |
||||
* @return Reference to self (for method chaining) |
||||
* |
||||
* If effective gain is higher than max gain, max gain is used. Note |
||||
* that this is done before listener gain is applied. Default is |
||||
* `1.0f`. If set to `0.0f`, the source is muted. |
||||
* @see @ref setMinGain(), @ref setGain(), @fn_al{Sourcef} with |
||||
* @def_al{MIN_GAIN} |
||||
*/ |
||||
Source& setMaxGain(Float gain) { |
||||
alSourcef(_id, AL_MAX_GAIN, gain); |
||||
return *this; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Set reference distance |
||||
* @return Reference to self (for method chaining) |
||||
* |
||||
* Default is `1.0f`. |
||||
* @see @ref setRolloffFactor(), @fn_al{Sourcef} with |
||||
* @def_al{REFERENCE_DISTANCE} |
||||
*/ |
||||
Source& setReferenceDistance(Float distance) { |
||||
alSourcef(_id, AL_REFERENCE_DISTANCE, distance); |
||||
return *this; |
||||
} |
||||
|
||||
/** @overload
|
||||
* @see @fn_al{Sourcei} with @def_al{REFERENCE_DISTANCE} |
||||
*/ |
||||
Source& setReferenceDistance(Int distance) { |
||||
alSourcei(_id, AL_REFERENCE_DISTANCE, distance); |
||||
return *this; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Set rolloff factor |
||||
* @return Reference to self (for method chaining) |
||||
* |
||||
* Default is `1.0f`. |
||||
* @see @ref setReferenceDistance(), @fn_al{Sourcef} with |
||||
* @def_al{ROLLOFF_FACTOR} |
||||
*/ |
||||
Source& setRolloffFactor(Float factor) { |
||||
alSourcef(_id, AL_ROLLOFF_FACTOR, factor); |
||||
return *this; |
||||
} |
||||
|
||||
/** @overload
|
||||
* @see @fn_al{Sourcei} with @def_al{ROLLOFF_FACTOR} |
||||
*/ |
||||
Source& setRolloffFactor(Int factor) { |
||||
alSourcei(_id, AL_ROLLOFF_FACTOR, factor); |
||||
return *this; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Set max distance |
||||
* @return Reference to self (for method chaining) |
||||
* |
||||
* Default is max representable value. |
||||
* @see @fn_al{Sourcef} with @def_al{MAX_DISTANCE} |
||||
*/ |
||||
Source& setMaxDistance(Float distance) { |
||||
alSourcef(_id, AL_MAX_DISTANCE, distance); |
||||
return *this; |
||||
} |
||||
|
||||
/** @overload
|
||||
* @see @fn_al{Sourcei} with @def_al{MAX_DISTANCE} |
||||
*/ |
||||
Source& setMaxDistance(Int distance) { |
||||
alSourcef(_id, AL_MAX_DISTANCE, distance); |
||||
return *this; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Set direction |
||||
* @return Reference to self (for method chaining) |
||||
* |
||||
* Default is `{0.0f, 0.0f, 0.0f}`, which means that the source is not |
||||
* directional. |
||||
* @see @ref setInnerConeAngle(), @ref setOuterConeAngle(), |
||||
* @ref setRelative(), @fn_al{Sourcefv} with @def_al{DIRECTION} |
||||
*/ |
||||
Source& setDirection(const Vector3& direction) { |
||||
alSourcefv(_id, AL_DIRECTION, direction.data()); |
||||
return *this; |
||||
} |
||||
|
||||
/** @overload
|
||||
* @see @fn_al{Sourceiv} with @def_al{DIRECTION} |
||||
*/ |
||||
Source& setDirection(const Vector3i& direction) { |
||||
alSourceiv(_id, AL_DIRECTION, direction.data()); |
||||
return *this; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Set inner cone angle |
||||
* @return Reference to self (for method chaining) |
||||
* |
||||
* Has effect only if the source is directional. Default is |
||||
* `360.0_degf`. |
||||
* @see @ref setOuterConeAngle(), @ref setDirection(), @fn_al{Sourcef} |
||||
* with @def_al{CONE_INNER_ANGLE} |
||||
*/ |
||||
Source& setInnerConeAngle(Deg angle) { |
||||
alSourcef(_id, AL_CONE_INNER_ANGLE, Float(angle)); |
||||
return *this; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Set outer cone angle |
||||
* @return Reference to self (for method chaining) |
||||
* |
||||
* Has effect only if the source is directional. Default is |
||||
* `360.0_degf`. |
||||
* @see @ref setInnerConeAngle(), @ref setDirection(), |
||||
* @ref setOuterConeGain() @fn_al{Sourcef} with |
||||
* @def_al{CONE_OUTER_ANGLE} |
||||
*/ |
||||
Source& setOuterConeAngle(Deg angle) { |
||||
alSourcef(_id, AL_CONE_OUTER_ANGLE, Float(angle)); |
||||
return *this; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Set outer cone gain multiplier |
||||
* @return Reference to self (for method chaining) |
||||
* |
||||
* The factor with which the gain is multiplied outside the outer cone. |
||||
* Default is `0.0f`. |
||||
* @see @ref setGain(), @ref setOuterConeAngle(), @fn_al{Sourcef} with |
||||
* @def_al{CONE_OUTER_GAIN} |
||||
*/ |
||||
Source& setOuterConeGain(Float multiplier) { |
||||
alSourcef(_id, AL_CONE_OUTER_ANGLE, multiplier); |
||||
return *this; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Set pitch |
||||
* @return Reference to self (for method chaining) |
||||
* |
||||
* Default is `1.0f`. |
||||
* @see @fn_al{Sourcef} with @def_al{PITCH} |
||||
*/ |
||||
Source& setPitch(Float pitch) { |
||||
alSourcef(_id, AL_PITCH, pitch); |
||||
return *this; |
||||
} |
||||
|
||||
/*@}*/ |
||||
|
||||
/** @{ @name Buffer management */ |
||||
|
||||
/**
|
||||
* @brief %Source type |
||||
* |
||||
* @see @ref type() |
||||
*/ |
||||
enum class Type: ALint { |
||||
Undetermined = AL_UNDETERMINED, /**< Undetermined (default) */ |
||||
Static = AL_STATIC, /**< Static source */ |
||||
Streaming = AL_STREAMING /**< Streaming source */ |
||||
}; |
||||
|
||||
/**
|
||||
* @brief Source type |
||||
* |
||||
* @see @ref setBuffer(), @fn_al{GetSourcei} with @def_al{SOURCE_TYPE} |
||||
*/ |
||||
Type type() const; |
||||
|
||||
/**
|
||||
* @brief Attach buffer |
||||
* @param buffer Buffer to attach or `nullptr` |
||||
* @return Reference to self (for method chaining) |
||||
* |
||||
* If an buffer is attached, changes source type to |
||||
* @ref Type "Type::Static", if detached, changes source type to |
||||
* @ref Type "Type::Undetermined". The buffer must be already filled |
||||
* with data. |
||||
* @see @ref type(), @fn_al{Sourcei} with @def_al{BUFFER} |
||||
*/ |
||||
Source& setBuffer(Buffer* buffer); |
||||
|
||||
/*@}*/ |
||||
|
||||
/** @{ @name State management */ |
||||
|
||||
/**
|
||||
* @brief %Source state |
||||
* |
||||
* @see @ref state(), @ref play(), @ref pause(), @ref stop(), |
||||
* @ref rewind() |
||||
*/ |
||||
enum class State: ALint { |
||||
Initial = AL_INITIAL, /**< Initial state (default) */ |
||||
Playing = AL_PLAYING, /**< The source is playing */ |
||||
Paused = AL_PAUSED, /**< The source is paused */ |
||||
Stopped = AL_STOPPED /**< The source is stopped */ |
||||
}; |
||||
|
||||
/**
|
||||
* @brief Play more sources at once |
||||
* |
||||
* The operation is guaranteed to be done for all sources at the same |
||||
* time. `nullptr` is not allowed. |
||||
* @see @ref play(), @ref pause(std::initializer_list<Source*>), |
||||
* @ref stop(std::initializer_list<Source*>), |
||||
* @ref rewind(std::initializer_list<Source*>), |
||||
* @fn_al{SourcePlayv} |
||||
*/ |
||||
static void play(std::initializer_list<Source*> sources); |
||||
static void play(const std::vector<Source*>& sources); /**< @overload */ |
||||
|
||||
/**
|
||||
* @brief Pause more sources at once |
||||
* |
||||
* The operation is guaranteed to be done for all sources at the same |
||||
* time. `nullptr` is not allowed. |
||||
* @see @ref pause(), @ref play(std::initializer_list<Source*>), |
||||
* @ref stop(std::initializer_list<Source*>), |
||||
* @ref rewind(std::initializer_list<Source*>), |
||||
* @fn_al{SourcePausev} |
||||
*/ |
||||
static void pause(std::initializer_list<Source*> sources); |
||||
static void pause(const std::vector<Source*>& sources); /**< @overload */ |
||||
|
||||
/**
|
||||
* @brief Stop more sources at once |
||||
* |
||||
* The operation is guaranteed to be done for all sources at the same |
||||
* time. `nullptr` is not allowed. |
||||
* @see @ref stop(), @ref play(std::initializer_list<Source*>), |
||||
* @ref pause(std::initializer_list<Source*>), |
||||
* @ref rewind(std::initializer_list<Source*>), |
||||
* @fn_al{SourceStopv} |
||||
*/ |
||||
static void stop(std::initializer_list<Source*> sources); |
||||
static void stop(const std::vector<Source*>& sources); /**< @overload */ |
||||
|
||||
/**
|
||||
* @brief Rewind more sources at once |
||||
* |
||||
* The operation is guaranteed to be done for all sources at the same |
||||
* time. `nullptr` is not allowed. |
||||
* @see @ref rewind(), @ref play(std::initializer_list<Source*>), |
||||
* @ref pause(std::initializer_list<Source*>), |
||||
* @ref stop(std::initializer_list<Source*>), |
||||
* @fn_al{SourceRewindv} |
||||
*/ |
||||
static void rewind(std::initializer_list<Source*> sources); |
||||
static void rewind(const std::vector<Source*>& sources); /**< @overload */ |
||||
|
||||
/**
|
||||
* @brief State |
||||
* |
||||
* @see @ref play(), @ref pause(), @ref stop(), @ref rewind(), |
||||
* @fn_al{GetSourcei} with @def_al{SOURCE_STATE} |
||||
*/ |
||||
State state() const; |
||||
|
||||
/**
|
||||
* @brief Play |
||||
* |
||||
* @see @ref play(std::initializer_list<Source*>), @ref state(), |
||||
* @ref pause(), @ref stop(), @ref rewind(), @fn_al{SourcePlay} |
||||
*/ |
||||
void play() { alSourcePlay(_id); } |
||||
|
||||
/**
|
||||
* @brief Pause |
||||
* |
||||
* @see @ref pause(std::initializer_list<Source*>), @ref state(), |
||||
* @ref play(), @ref stop(), @ref rewind(), @fn_al{SourcePause} |
||||
*/ |
||||
void pause() { alSourcePause(_id); } |
||||
|
||||
/**
|
||||
* @brief Stop |
||||
* |
||||
* @see @ref stop(std::initializer_list<Source*>), @ref state(), |
||||
* @ref play(), @ref pause(), @ref rewind(), @fn_al{SourceStop} |
||||
*/ |
||||
void stop() { alSourceStop(_id); } |
||||
|
||||
/**
|
||||
* @brief Rewind |
||||
* |
||||
* @see @ref rewind(std::initializer_list<Source*>), @ref state(), |
||||
* @ref play(), @ref pause(), @ref stop(), @fn_al{SourceRewind} |
||||
*/ |
||||
void rewind() { alSourceRewind(_id); } |
||||
|
||||
/**
|
||||
* @brief Whether the source is looping |
||||
* |
||||
* @see @fn_al{GetSourcei} with @def_al{LOOPING} |
||||
*/ |
||||
bool isLooping() const; |
||||
|
||||
/**
|
||||
* @brief Set source looping |
||||
* @return Reference to self (for method chaining) |
||||
* |
||||
* Default is `false`. |
||||
* @see @fn_al{Sourcei} with @def_al{LOOPING} |
||||
*/ |
||||
Source& setLooping(bool loop) { |
||||
alSourcei(_id, AL_LOOPING, loop); |
||||
return *this; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Offset in seconds |
||||
* |
||||
* @see @ref offsetInBytes(), @ref offsetInSamples(), |
||||
* @fn_al{GetSourcef} with @def_al{SEC_OFFSET} |
||||
*/ |
||||
Float offsetInSeconds() const; |
||||
|
||||
/**
|
||||
* @brief Set offset in seconds |
||||
* @return Reference to self (for method chaining) |
||||
* |
||||
* @see @ref setOffsetInBytes(), @ref setOffsetInSamples(), |
||||
* @fn_al{Sourcef} with @def_al{SEC_OFFSET} |
||||
*/ |
||||
Source& setOffsetInSeconds(Float offset) { |
||||
alSourcef(_id, AL_SEC_OFFSET, offset); |
||||
return *this; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Offset in bytes |
||||
* |
||||
* @see @ref offsetInSeconds(), @ref offsetInSamples(), |
||||
* @fn_al{GetSourcei} with @def_al{BYTE_OFFSET} |
||||
*/ |
||||
Int offsetInBytes() const; |
||||
|
||||
/**
|
||||
* @brief Set offset in bytes |
||||
* @return Reference to self (for method chaining) |
||||
* |
||||
* @see @ref setOffsetInSeconds(), @ref setOffsetInSamples(), |
||||
* @fn_al{Sourcei} with @def_al{SEC_OFFSET} |
||||
*/ |
||||
Source& setOffsetInBytes(Int offset) { |
||||
alSourcei(_id, AL_BYTE_OFFSET, offset); |
||||
return *this; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Offset in samples |
||||
* |
||||
* @see @ref offsetInSeconds(), @ref offsetInBytes(), |
||||
* @fn_al{GetSourcei} with @def_al{SAMPLE_OFFSET} |
||||
*/ |
||||
Int offsetInSamples() const; |
||||
|
||||
/**
|
||||
* @brief Set offset in samples |
||||
* @return Reference to self (for method chaining) |
||||
* |
||||
* @see @ref setOffsetInSeconds(), @ref setOffsetInBytes(), |
||||
* @fn_al{Sourcei} with @def_al{SEC_OFFSET} |
||||
*/ |
||||
Source& setOffsetInSamples(Int offset) { |
||||
alSourcei(_id, AL_SAMPLE_OFFSET, offset); |
||||
return *this; |
||||
} |
||||
|
||||
/*@}*/ |
||||
|
||||
private: |
||||
ALuint _id; |
||||
}; |
||||
|
||||
/** @debugoperator{Magnum::Audio::Source} */ |
||||
Debug MAGNUM_AUDIO_EXPORT operator<<(Debug debug, Source::State value); |
||||
|
||||
inline Source::Source(Source&& other): _id(other._id) { |
||||
other._id = 0; |
||||
} |
||||
|
||||
inline Source& Source::operator=(Source&& other) { |
||||
std::swap(_id, other._id); |
||||
return *this; |
||||
} |
||||
|
||||
auto Source::state() const -> State { |
||||
ALint state; |
||||
alGetSourcei(_id, AL_SOURCE_STATE, &state); |
||||
return State(state); |
||||
} |
||||
|
||||
inline bool Source::isLooping() const { |
||||
ALint looping; |
||||
alGetSourcei(_id, AL_LOOPING, &looping); |
||||
return looping; |
||||
} |
||||
|
||||
inline Float Source::offsetInSeconds() const { |
||||
Float offset; |
||||
alGetSourcef(_id, AL_SEC_OFFSET, &offset); |
||||
return offset; |
||||
} |
||||
|
||||
inline Int Source::offsetInBytes() const { |
||||
Int offset; |
||||
alGetSourcei(_id, AL_BYTE_OFFSET, &offset); |
||||
return offset; |
||||
} |
||||
|
||||
inline Int Source::offsetInSamples() const { |
||||
Int offset; |
||||
alGetSourcei(_id, AL_SAMPLE_OFFSET, &offset); |
||||
return offset; |
||||
} |
||||
|
||||
}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,76 @@
|
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#include <Containers/Array.h> |
||||
#include <TestSuite/Tester.h> |
||||
#include <Utility/Directory.h> |
||||
|
||||
#include "Audio/AbstractImporter.h" |
||||
|
||||
#include "testConfigure.h" |
||||
|
||||
namespace Magnum { namespace Audio { namespace Test { |
||||
|
||||
class AbstractImporterTest: public TestSuite::Tester { |
||||
public: |
||||
explicit AbstractImporterTest(); |
||||
|
||||
void openFile(); |
||||
}; |
||||
|
||||
AbstractImporterTest::AbstractImporterTest() { |
||||
addTests({&AbstractImporterTest::openFile}); |
||||
} |
||||
|
||||
void AbstractImporterTest::openFile() { |
||||
class DataImporter: public Audio::AbstractImporter { |
||||
public: |
||||
explicit DataImporter(): opened(false) {} |
||||
|
||||
private: |
||||
Features doFeatures() const override { return Feature::OpenData; } |
||||
bool doIsOpened() const override { return opened; } |
||||
void doClose() override {} |
||||
|
||||
void doOpenData(Containers::ArrayReference<const unsigned char> data) override { |
||||
opened = (data.size() == 1 && data[0] == 0xa5); |
||||
} |
||||
|
||||
Buffer::Format doFormat() const override { return {}; } |
||||
UnsignedInt doFrequency() const override { return {}; } |
||||
Corrade::Containers::Array<unsigned char> doData() override { return nullptr; } |
||||
|
||||
bool opened; |
||||
}; |
||||
|
||||
/* doOpenFile() should call doOpenData() */ |
||||
DataImporter importer; |
||||
CORRADE_VERIFY(!importer.isOpened()); |
||||
importer.openFile(Utility::Directory::join(AUDIO_TEST_DIR, "file.bin")); |
||||
CORRADE_VERIFY(importer.isOpened()); |
||||
} |
||||
|
||||
}}} |
||||
|
||||
CORRADE_TEST_MAIN(Magnum::Audio::Test::AbstractImporterTest) |
||||
@ -0,0 +1,51 @@
|
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#include <sstream> |
||||
#include <TestSuite/Tester.h> |
||||
|
||||
#include "Audio/Buffer.h" |
||||
|
||||
namespace Magnum { namespace Audio { namespace Test { |
||||
|
||||
class BufferTest: public TestSuite::Tester { |
||||
public: |
||||
explicit BufferTest(); |
||||
|
||||
void debugFormat(); |
||||
}; |
||||
|
||||
BufferTest::BufferTest() { |
||||
addTests({&BufferTest::debugFormat}); |
||||
} |
||||
|
||||
void BufferTest::debugFormat() { |
||||
std::ostringstream out; |
||||
Debug(&out) << Buffer::Format::Stereo16; |
||||
CORRADE_COMPARE(out.str(), "Audio::Buffer::Format::Stereo16\n"); |
||||
} |
||||
|
||||
}}} |
||||
|
||||
CORRADE_TEST_MAIN(Magnum::Audio::Test::BufferTest) |
||||
@ -0,0 +1,33 @@
|
||||
# |
||||
# This file is part of Magnum. |
||||
# |
||||
# Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
# |
||||
# Permission is hereby granted, free of charge, to any person obtaining a |
||||
# copy of this software and associated documentation files (the "Software"), |
||||
# to deal in the Software without restriction, including without limitation |
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
# and/or sell copies of the Software, and to permit persons to whom the |
||||
# Software is furnished to do so, subject to the following conditions: |
||||
# |
||||
# The above copyright notice and this permission notice shall be included |
||||
# in all copies or substantial portions of the Software. |
||||
# |
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
# DEALINGS IN THE SOFTWARE. |
||||
# |
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/testConfigure.h.cmake |
||||
${CMAKE_CURRENT_BINARY_DIR}/testConfigure.h) |
||||
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR}) |
||||
|
||||
corrade_add_test(AudioAbstractImporterTest AbstractImporterTest.cpp LIBRARIES MagnumAudio) |
||||
corrade_add_test(AudioBufferTest BufferTest.cpp LIBRARIES MagnumAudio) |
||||
corrade_add_test(AudioRendererTest RendererTest.cpp LIBRARIES MagnumAudio) |
||||
corrade_add_test(AudioSourceTest SourceTest.cpp LIBRARIES MagnumAudio) |
||||
@ -0,0 +1,51 @@
|
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#include <sstream> |
||||
#include <TestSuite/Tester.h> |
||||
|
||||
#include "Audio/Renderer.h" |
||||
|
||||
namespace Magnum { namespace Audio { namespace Test { |
||||
|
||||
class RendererTest: public TestSuite::Tester { |
||||
public: |
||||
explicit RendererTest(); |
||||
|
||||
void debugError(); |
||||
}; |
||||
|
||||
RendererTest::RendererTest() { |
||||
addTests({&RendererTest::debugError}); |
||||
} |
||||
|
||||
void RendererTest::debugError() { |
||||
std::ostringstream out; |
||||
Debug(&out) << Renderer::Error::InvalidOperation; |
||||
CORRADE_COMPARE(out.str(), "Audio::Renderer::Error::InvalidOperation\n"); |
||||
} |
||||
|
||||
}}} |
||||
|
||||
CORRADE_TEST_MAIN(Magnum::Audio::Test::RendererTest) |
||||
@ -0,0 +1,51 @@
|
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#include <sstream> |
||||
#include <TestSuite/Tester.h> |
||||
|
||||
#include "Audio/Source.h" |
||||
|
||||
namespace Magnum { namespace Audio { namespace Test { |
||||
|
||||
class SourceTest: public TestSuite::Tester { |
||||
public: |
||||
explicit SourceTest(); |
||||
|
||||
void debugState(); |
||||
}; |
||||
|
||||
SourceTest::SourceTest() { |
||||
addTests({&SourceTest::debugState}); |
||||
} |
||||
|
||||
void SourceTest::debugState() { |
||||
std::ostringstream out; |
||||
Debug(&out) << Source::State::Playing; |
||||
CORRADE_COMPARE(out.str(), "Audio::Source::State::Playing\n"); |
||||
} |
||||
|
||||
}}} |
||||
|
||||
CORRADE_TEST_MAIN(Magnum::Audio::Test::SourceTest) |
||||
@ -0,0 +1,25 @@
|
||||
/* |
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#define AUDIO_TEST_DIR "${CMAKE_CURRENT_SOURCE_DIR}" |
||||
@ -0,0 +1,35 @@
|
||||
#ifndef Magnum_Audio_magnumAudioVisibility_h |
||||
#define Magnum_Audio_magnumAudioVisibility_h |
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#include <Utility/Visibility.h> |
||||
|
||||
#ifdef MagnumAudio_EXPORTS |
||||
#define MAGNUM_AUDIO_EXPORT CORRADE_VISIBILITY_EXPORT |
||||
#else |
||||
#define MAGNUM_AUDIO_EXPORT CORRADE_VISIBILITY_IMPORT |
||||
#endif |
||||
|
||||
#endif |
||||
@ -0,0 +1,116 @@
|
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#include "CapsuleRenderer.h" |
||||
|
||||
#include "MeshView.h" |
||||
#include "DebugTools/ResourceManager.h" |
||||
#include "DebugTools/ShapeRenderer.h" |
||||
#include "Primitives/Capsule.h" |
||||
#include "Shapes/Capsule.h" |
||||
#include "Shaders/Flat.h" |
||||
#include "Trade/MeshData2D.h" |
||||
#include "Trade/MeshData3D.h" |
||||
|
||||
#include "DebugTools/Implementation/CapsuleRendererTransformation.h" |
||||
|
||||
namespace Magnum { namespace DebugTools { namespace Implementation { |
||||
|
||||
AbstractCapsuleRenderer<2>::AbstractCapsuleRenderer(): AbstractShapeRenderer<2>("capsule2d", "capsule2d-vertices", "capsule2d-indices") { |
||||
constexpr UnsignedInt rings = 10; |
||||
if(!wireframeMesh) createResources(Primitives::Capsule2D::wireframe(rings, 1, 1.0f)); |
||||
|
||||
/* Bottom hemisphere */ |
||||
if(!(bottom = ResourceManager::instance().get<MeshView>("capsule2d-bottom"))) { |
||||
auto view = new MeshView(wireframeMesh); |
||||
view->setIndexRange(0, rings*4, 0, rings*2+1); |
||||
ResourceManager::instance().set(bottom.key(), view, ResourceDataState::Final, ResourcePolicy::Manual); |
||||
} |
||||
|
||||
/* Cylinder */ |
||||
if(!(cylinder = ResourceManager::instance().get<MeshView>("capsule2d-cylinder"))) { |
||||
auto view = new MeshView(wireframeMesh); |
||||
view->setIndexRange(rings*4, 4, rings*2+1, rings*2+3); |
||||
ResourceManager::instance().set(cylinder.key(), view, ResourceDataState::Final, ResourcePolicy::Manual); |
||||
} |
||||
|
||||
/* Top hemisphere */ |
||||
if(!(top = ResourceManager::instance().get<MeshView>("capsule2d-top"))) { |
||||
auto view = new MeshView(wireframeMesh); |
||||
view->setIndexRange(rings*4+4, rings*4, rings*2+3, rings*4+4); |
||||
ResourceManager::instance().set(top.key(), view, ResourceDataState::Final, ResourcePolicy::Manual); |
||||
} |
||||
} |
||||
|
||||
AbstractCapsuleRenderer<3>::AbstractCapsuleRenderer(): AbstractShapeRenderer<3>("capsule3d", "capsule3d-vertices", "capsule3d-indices") { |
||||
constexpr UnsignedInt rings = 10; |
||||
constexpr UnsignedInt segments = 40; |
||||
if(!wireframeMesh) createResources(Primitives::Capsule3D::wireframe(rings, 1, segments, 1.0f)); |
||||
|
||||
/* Bottom hemisphere */ |
||||
if(!(bottom = ResourceManager::instance().get<MeshView>("capsule3d-bottom"))) { |
||||
auto view = new MeshView(wireframeMesh); |
||||
view->setIndexRange(0, rings*8, 0, rings*4+1); |
||||
ResourceManager::instance().set(bottom.key(), view, ResourceDataState::Final, ResourcePolicy::Manual); |
||||
} |
||||
|
||||
/* Cylinder */ |
||||
if(!(cylinder = ResourceManager::instance().get<MeshView>("capsule3d-cylinder"))) { |
||||
auto view = new MeshView(wireframeMesh); |
||||
view->setIndexRange(rings*8, segments*4+8, rings*4+1, rings*4+segments*2+5); |
||||
ResourceManager::instance().set(cylinder.key(), view, ResourceDataState::Final, ResourcePolicy::Manual); |
||||
} |
||||
|
||||
/* Top */ |
||||
if(!(top = ResourceManager::instance().get<MeshView>("capsule3d-top"))) { |
||||
auto view = new MeshView(wireframeMesh); |
||||
view->setIndexRange(rings*8+segments*4+8, rings*8, rings*4+segments*2+5, rings*8+segments*2+6); |
||||
ResourceManager::instance().set(top.key(), view, ResourceDataState::Final, ResourcePolicy::Manual); |
||||
} |
||||
} |
||||
|
||||
template<UnsignedInt dimensions> CapsuleRenderer<dimensions>::CapsuleRenderer(const Shapes::Implementation::AbstractShape<dimensions>& capsule): capsule(static_cast<const Shapes::Implementation::Shape<Shapes::Capsule<dimensions>>&>(capsule).shape) {} |
||||
|
||||
template<UnsignedInt dimensions> void CapsuleRenderer<dimensions>::draw(Resource<ShapeRendererOptions>& options, const typename DimensionTraits<dimensions, Float>::MatrixType& projectionMatrix) { |
||||
std::array<typename DimensionTraits<dimensions, Float>::MatrixType, 3> transformations = Implementation::capsuleRendererTransformation<dimensions>(capsule.a(), capsule.b(), capsule.radius()); |
||||
AbstractShapeRenderer<dimensions>::wireframeShader->setColor(options->color()) |
||||
.use(); |
||||
|
||||
/* Bottom */ |
||||
AbstractShapeRenderer<dimensions>::wireframeShader->setTransformationProjectionMatrix(projectionMatrix*transformations[0]); |
||||
AbstractCapsuleRenderer<dimensions>::bottom->draw(); |
||||
|
||||
/* Cylinder */ |
||||
AbstractShapeRenderer<dimensions>::wireframeShader->setTransformationProjectionMatrix(projectionMatrix*transformations[1]); |
||||
AbstractCapsuleRenderer<dimensions>::cylinder->draw(); |
||||
|
||||
/* Top */ |
||||
AbstractShapeRenderer<dimensions>::wireframeShader->setTransformationProjectionMatrix(projectionMatrix*transformations[2]); |
||||
AbstractCapsuleRenderer<dimensions>::top->draw(); |
||||
} |
||||
|
||||
template class CapsuleRenderer<2>; |
||||
template class CapsuleRenderer<3>; |
||||
|
||||
}}} |
||||
@ -0,0 +1,66 @@
|
||||
#ifndef Magnum_DebugTools_Implementation_CapsuleRenderer_h |
||||
#define Magnum_DebugTools_Implementation_CapsuleRenderer_h |
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#include "AbstractShapeRenderer.h" |
||||
|
||||
#include "Shapes/Shapes.h" |
||||
|
||||
#include "corradeCompatibility.h" |
||||
|
||||
namespace Magnum { namespace DebugTools { namespace Implementation { |
||||
|
||||
template<UnsignedInt dimensions> class AbstractCapsuleRenderer; |
||||
|
||||
template<> class AbstractCapsuleRenderer<2>: public AbstractShapeRenderer<2> { |
||||
public: |
||||
explicit AbstractCapsuleRenderer(); |
||||
|
||||
protected: |
||||
Resource<MeshView> bottom, cylinder, top; |
||||
}; |
||||
|
||||
template<> class AbstractCapsuleRenderer<3>: public AbstractShapeRenderer<3> { |
||||
public: |
||||
explicit AbstractCapsuleRenderer(); |
||||
|
||||
protected: |
||||
Resource<MeshView> bottom, cylinder, top; |
||||
}; |
||||
|
||||
template<UnsignedInt dimensions> class CapsuleRenderer: public AbstractCapsuleRenderer<dimensions> { |
||||
public: |
||||
explicit CapsuleRenderer(const Shapes::Implementation::AbstractShape<dimensions>& capsule); |
||||
CapsuleRenderer(const Shapes::Implementation::AbstractShape<dimensions>&&) = delete; |
||||
|
||||
void draw(Resource<ShapeRendererOptions>& options, const typename DimensionTraits<dimensions, Float>::MatrixType& projectionMatrix) override; |
||||
|
||||
private: |
||||
const Shapes::Capsule<dimensions>& capsule; |
||||
}; |
||||
|
||||
}}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,106 @@
|
||||
#ifndef Magnum_DebugTools_Implementation_ForceRendererTransformation_h |
||||
#define Magnum_DebugTools_Implementation_ForceRendererTransformation_h |
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#include <array> |
||||
|
||||
#include "Math/Functions.h" |
||||
#include "Math/Matrix3.h" |
||||
#include "Math/Matrix4.h" |
||||
#include "Magnum.h" |
||||
#include "DimensionTraits.h" |
||||
|
||||
namespace Magnum { namespace DebugTools { namespace Implementation { |
||||
|
||||
template<UnsignedInt dimensions> std::array<typename DimensionTraits<dimensions, Float>::MatrixType, 3> capsuleRendererTransformation(const typename DimensionTraits<dimensions, Float>::VectorType& a, const typename DimensionTraits<dimensions, Float>::VectorType& b, Float radius); |
||||
|
||||
template<> std::array<Matrix3, 3> capsuleRendererTransformation<2>(const Vector2& a, const Vector2& b, const Float radius) { |
||||
/* Vector from capsule center to top hemisphere center */ |
||||
const Vector2 direction = 0.5f*(b - a); |
||||
const Float length = direction.length(); |
||||
|
||||
/* Capsule rotation and distance to caps after they are scaled to proper
|
||||
radius (if nonzero cylinder length) */ |
||||
Matrix3 rotation; |
||||
Vector2 capDistance; |
||||
if(length >= Math::TypeTraits<Float>::epsilon()) { |
||||
rotation.up() = direction/length; |
||||
rotation.right() = rotation.up().perpendicular(); |
||||
CORRADE_INTERNAL_ASSERT(rotation.right().isNormalized()); |
||||
|
||||
capDistance = direction*(radius/length); |
||||
} |
||||
|
||||
/* Scaling and translation of all parts */ |
||||
const auto rotationScaling = rotation*Matrix3::scaling(Vector2(radius)); |
||||
return {{ |
||||
Matrix3::translation(a+capDistance)*rotationScaling, |
||||
Matrix3::translation(0.5f*(a + b))*rotation*Matrix3::scaling({radius, length}), |
||||
Matrix3::translation(b-capDistance)*rotationScaling |
||||
}}; |
||||
} |
||||
|
||||
template<> std::array<Matrix4, 3> capsuleRendererTransformation<3>(const Vector3& a, const Vector3& b, const Float radius) { |
||||
/* Vector from capsule center to top hemisphere center */ |
||||
const Vector3 direction = 0.5f*(b - a); |
||||
const Float length = direction.length(); |
||||
|
||||
/* Capsule rotation and distance to caps after they are scaled to proper
|
||||
radius (if nonzero cylinder length) */ |
||||
Matrix4 rotation; |
||||
Vector3 capDistance; |
||||
if(length >= Math::TypeTraits<Float>::epsilon()) { |
||||
const Vector3 directionNormalized = direction/length; |
||||
const Float dot = Vector3::dot(directionNormalized, Vector3::zAxis()); |
||||
|
||||
/* Direction is parallel to Z axis, special rotation case */ |
||||
if(Math::abs(dot) > 1.0f - Math::TypeTraits<Float>::epsilon()) { |
||||
rotation.up() = dot*Vector3::zAxis(); |
||||
rotation.right() = Vector3::xAxis(); |
||||
rotation.backward() = -dot*Vector3::yAxis(); |
||||
|
||||
/* Common case */ |
||||
} else { |
||||
rotation.up() = directionNormalized; |
||||
rotation.right() = Vector3::cross(rotation.up(), Vector3::zAxis()).normalized(); |
||||
rotation.backward() = Vector3::cross(rotation.right(), rotation.up()); |
||||
CORRADE_INTERNAL_ASSERT(rotation.up().isNormalized() && rotation.backward().isNormalized()); |
||||
} |
||||
|
||||
capDistance = directionNormalized*radius; |
||||
} |
||||
|
||||
/* Scaling and translation of all parts */ |
||||
const auto rotationScaling = rotation*Matrix4::scaling(Vector3(radius)); |
||||
return {{ |
||||
Matrix4::translation(a+capDistance)*rotationScaling, |
||||
Matrix4::translation(0.5f*(a + b))*rotation*Matrix4::scaling({radius, length, radius}), |
||||
Matrix4::translation(b-capDistance)*rotationScaling |
||||
}}; |
||||
} |
||||
|
||||
}}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,61 @@
|
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#include "CylinderRenderer.h" |
||||
|
||||
#include "Mesh.h" |
||||
#include "DebugTools/ShapeRenderer.h" |
||||
#include "Shapes/Cylinder.h" |
||||
#include "Primitives/Cylinder.h" |
||||
#include "Primitives/Square.h" |
||||
#include "Shaders/Flat.h" |
||||
#include "Trade/MeshData2D.h" |
||||
#include "Trade/MeshData3D.h" |
||||
|
||||
#include "DebugTools/Implementation/CylinderRendererTransformation.h" |
||||
|
||||
namespace Magnum { namespace DebugTools { namespace Implementation { |
||||
|
||||
AbstractCylinderRenderer<2>::AbstractCylinderRenderer(): AbstractShapeRenderer<2>("cylinder2d", "cylinder2d-vertices", {}) { |
||||
if(!wireframeMesh) createResources(Primitives::Square::wireframe()); |
||||
} |
||||
|
||||
AbstractCylinderRenderer<3>::AbstractCylinderRenderer(): AbstractShapeRenderer<3>("cylinder3d", "cylinder3d-vertices", "cylinder3d-indices") { |
||||
if(!wireframeMesh) createResources(Primitives::Cylinder::wireframe(1, 40, 1.0f)); |
||||
} |
||||
|
||||
template<UnsignedInt dimensions> CylinderRenderer<dimensions>::CylinderRenderer(const Shapes::Implementation::AbstractShape<dimensions>& cylinder): cylinder(static_cast<const Shapes::Implementation::Shape<Shapes::Cylinder<dimensions>>&>(cylinder).shape) {} |
||||
|
||||
template<UnsignedInt dimensions> void CylinderRenderer<dimensions>::draw(Resource<ShapeRendererOptions>& options, const typename DimensionTraits<dimensions, Float>::MatrixType& projectionMatrix) { |
||||
AbstractShapeRenderer<dimensions>::wireframeShader->setTransformationProjectionMatrix(projectionMatrix* |
||||
Implementation::cylinderRendererTransformation<dimensions>(cylinder.a(), cylinder.b(), cylinder.radius())) |
||||
.setColor(options->color()) |
||||
.use(); |
||||
AbstractShapeRenderer<dimensions>::wireframeMesh->draw(); |
||||
} |
||||
|
||||
template class CylinderRenderer<2>; |
||||
template class CylinderRenderer<3>; |
||||
|
||||
}}} |
||||
@ -0,0 +1,60 @@
|
||||
#ifndef Magnum_DebugTools_Implementation_CylinderRenderer_h |
||||
#define Magnum_DebugTools_Implementation_CylinderRenderer_h |
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#include "AbstractShapeRenderer.h" |
||||
|
||||
#include "Shapes/Shapes.h" |
||||
|
||||
#include "corradeCompatibility.h" |
||||
|
||||
namespace Magnum { namespace DebugTools { namespace Implementation { |
||||
|
||||
template<UnsignedInt dimensions> class AbstractCylinderRenderer; |
||||
|
||||
template<> class AbstractCylinderRenderer<2>: public AbstractShapeRenderer<2> { |
||||
public: |
||||
explicit AbstractCylinderRenderer(); |
||||
}; |
||||
|
||||
template<> class AbstractCylinderRenderer<3>: public AbstractShapeRenderer<3> { |
||||
public: |
||||
explicit AbstractCylinderRenderer(); |
||||
}; |
||||
|
||||
template<UnsignedInt dimensions> class CylinderRenderer: public AbstractCylinderRenderer<dimensions> { |
||||
public: |
||||
explicit CylinderRenderer(const Shapes::Implementation::AbstractShape<dimensions>& cylinder); |
||||
CylinderRenderer(const Shapes::Implementation::AbstractShape<dimensions>&&) = delete; |
||||
|
||||
void draw(Resource<ShapeRendererOptions>& options, const typename DimensionTraits<dimensions, Float>::MatrixType& projectionMatrix) override; |
||||
|
||||
private: |
||||
const Shapes::Cylinder<dimensions>& cylinder; |
||||
}; |
||||
|
||||
}}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,88 @@
|
||||
#ifndef Magnum_DebugTools_Implementation_ForceRendererTransformation_h |
||||
#define Magnum_DebugTools_Implementation_ForceRendererTransformation_h |
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#include "Math/Functions.h" |
||||
#include "Math/Matrix3.h" |
||||
#include "Math/Matrix4.h" |
||||
#include "Magnum.h" |
||||
#include "DimensionTraits.h" |
||||
|
||||
namespace Magnum { namespace DebugTools { namespace Implementation { |
||||
|
||||
template<UnsignedInt dimensions> typename DimensionTraits<dimensions, Float>::MatrixType cylinderRendererTransformation(const typename DimensionTraits<dimensions, Float>::VectorType& a, const typename DimensionTraits<dimensions, Float>::VectorType& b, Float radius); |
||||
|
||||
template<> Matrix3 cylinderRendererTransformation<2>(const Vector2& a, const Vector2& b, const Float radius) { |
||||
/* Vector from cylinder center to top hemisphere center */ |
||||
const Vector2 direction = 0.5f*(b - a); |
||||
const Float length = direction.length(); |
||||
|
||||
/* Capsule rotation and distance to caps after they are scaled to proper
|
||||
radius (if nonzero cylinder length) */ |
||||
Matrix3 rotation; |
||||
if(length >= Math::TypeTraits<Float>::epsilon()) { |
||||
rotation.up() = direction/length; |
||||
rotation.right() = rotation.up().perpendicular(); |
||||
CORRADE_INTERNAL_ASSERT(rotation.right().isNormalized()); |
||||
} |
||||
|
||||
/* Scaling and translation */ |
||||
return Matrix3::translation(0.5f*(a + b))*rotation*Matrix3::scaling({radius, length}); |
||||
} |
||||
|
||||
template<> Matrix4 cylinderRendererTransformation<3>(const Vector3& a, const Vector3& b, const Float radius) { |
||||
/* Vector from cylinder center to top hemisphere center */ |
||||
const Vector3 direction = 0.5f*(b - a); |
||||
const Float length = direction.length(); |
||||
|
||||
/* Capsule rotation and distance to caps after they are scaled to proper
|
||||
radius (if nonzero cylinder length) */ |
||||
Matrix4 rotation; |
||||
if(length >= Math::TypeTraits<Float>::epsilon()) { |
||||
const Vector3 directionNormalized = direction/length; |
||||
const Float dot = Vector3::dot(directionNormalized, Vector3::zAxis()); |
||||
|
||||
/* Direction is parallel to Z axis, special rotation case */ |
||||
if(Math::abs(dot) > 1.0f - Math::TypeTraits<Float>::epsilon()) { |
||||
rotation.up() = dot*Vector3::zAxis(); |
||||
rotation.right() = Vector3::xAxis(); |
||||
rotation.backward() = -dot*Vector3::yAxis(); |
||||
|
||||
/* Common case */ |
||||
} else { |
||||
rotation.up() = directionNormalized; |
||||
rotation.right() = Vector3::cross(rotation.up(), Vector3::zAxis()).normalized(); |
||||
rotation.backward() = Vector3::cross(rotation.right(), rotation.up()); |
||||
CORRADE_INTERNAL_ASSERT(rotation.up().isNormalized() && rotation.backward().isNormalized()); |
||||
} |
||||
} |
||||
|
||||
/* Scaling and translation */ |
||||
return Matrix4::translation(0.5f*(a + b))*rotation*Matrix4::scaling({radius, length, radius}); |
||||
} |
||||
|
||||
}}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,177 @@
|
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#include <TestSuite/Tester.h> |
||||
|
||||
#include "DebugTools/Implementation/CapsuleRendererTransformation.h" |
||||
|
||||
namespace Magnum { namespace DebugTools { namespace Test { |
||||
|
||||
class CapsuleRendererTest: public TestSuite::Tester { |
||||
public: |
||||
explicit CapsuleRendererTest(); |
||||
|
||||
void zeroLength2D(); |
||||
void common2D(); |
||||
|
||||
void zeroLength3D(); |
||||
void parallel3D(); |
||||
void antiParallel3D(); |
||||
void common3D(); |
||||
}; |
||||
|
||||
CapsuleRendererTest::CapsuleRendererTest() { |
||||
addTests({&CapsuleRendererTest::zeroLength2D, |
||||
&CapsuleRendererTest::common2D, |
||||
|
||||
&CapsuleRendererTest::zeroLength3D, |
||||
&CapsuleRendererTest::parallel3D, |
||||
&CapsuleRendererTest::antiParallel3D, |
||||
&CapsuleRendererTest::common3D}); |
||||
} |
||||
|
||||
void CapsuleRendererTest::zeroLength2D() { |
||||
const Vector2 a(0.5f, 3.0f); |
||||
std::array<Matrix3, 3> transformation = Implementation::capsuleRendererTransformation<2>(a, a, 3.5f); |
||||
|
||||
const auto scaling = Math::Matrix<2, Float>::fromDiagonal(Vector2(3.5f)); |
||||
CORRADE_COMPARE(transformation[0].rotationScaling(), scaling); |
||||
CORRADE_COMPARE(transformation[1].rotationScaling(), (Math::Matrix<2, Float>::fromDiagonal({3.5f, 0.0f}))); |
||||
CORRADE_COMPARE(transformation[2].rotationScaling(), scaling); |
||||
|
||||
CORRADE_COMPARE(transformation[0].translation(), a); |
||||
CORRADE_COMPARE(transformation[1].translation(), a); |
||||
CORRADE_COMPARE(transformation[2].translation(), a); |
||||
} |
||||
|
||||
void CapsuleRendererTest::common2D() { |
||||
const Vector2 a(0.5f, 3.0f); |
||||
const Vector2 b(7.5f, -1.0f); |
||||
std::array<Matrix3, 3> transformation = Implementation::capsuleRendererTransformation<2>(a, b, 3.5f); |
||||
|
||||
/* Vector from capsule center to top hemisphere center */ |
||||
const Vector2 up(3.5f, -2.0f); |
||||
CORRADE_COMPARE(transformation[0].up(), up.resized(3.5f)); |
||||
CORRADE_COMPARE(transformation[1].up(), up); |
||||
CORRADE_COMPARE(transformation[2].up(), up.resized(3.5f)); |
||||
|
||||
const auto right = Vector2(4.0f, 7.0f).resized(3.5f); |
||||
CORRADE_COMPARE(transformation[0].right(), right); |
||||
CORRADE_COMPARE(transformation[1].right(), right); |
||||
CORRADE_COMPARE(transformation[2].right(), right); |
||||
|
||||
/* Orthogonality */ |
||||
CORRADE_COMPARE(Vector2::dot(transformation[0].up(), transformation[0].right()), 0.0f); |
||||
|
||||
const Vector2 capDistance = up.resized(3.5f); |
||||
CORRADE_COMPARE(transformation[0].translation(), a+capDistance); |
||||
CORRADE_COMPARE(transformation[1].translation(), 0.5f*(a + b)); |
||||
CORRADE_COMPARE(transformation[2].translation(), b-capDistance); |
||||
} |
||||
|
||||
void CapsuleRendererTest::zeroLength3D() { |
||||
const Vector3 a(0.5f, 3.0f, 7.0f); |
||||
std::array<Matrix4, 3> transformation = Implementation::capsuleRendererTransformation<3>(a, a, 3.5f); |
||||
|
||||
const auto scaling = Math::Matrix<3, Float>::fromDiagonal(Vector3(3.5f)); |
||||
CORRADE_COMPARE(transformation[0].rotationScaling(), scaling); |
||||
CORRADE_COMPARE(transformation[1].rotationScaling(), (Math::Matrix<3, Float>::fromDiagonal({3.5f, 0.0f, 3.5f}))); |
||||
CORRADE_COMPARE(transformation[2].rotationScaling(), scaling); |
||||
|
||||
CORRADE_COMPARE(transformation[0].translation(), a); |
||||
CORRADE_COMPARE(transformation[1].translation(), a); |
||||
CORRADE_COMPARE(transformation[2].translation(), a); |
||||
} |
||||
|
||||
void CapsuleRendererTest::parallel3D() { |
||||
const Vector3 a(0.5f, 3.0f, 7.0f); |
||||
const Vector3 b(0.5f, 3.0f, 11.0f); |
||||
std::array<Matrix4, 3> transformation = Implementation::capsuleRendererTransformation<3>(a, b, 3.5f); |
||||
|
||||
const auto rotation = Matrix4::rotationX(Deg(90.0f)); |
||||
const auto scaling = (rotation*Matrix4::scaling(Vector3(3.5f))).rotationScaling(); |
||||
CORRADE_COMPARE(transformation[0].rotationScaling(), scaling); |
||||
CORRADE_COMPARE(transformation[1].rotationScaling(), |
||||
(rotation*Matrix4::scaling({3.5f, 2.0f, 3.5f})).rotationScaling()); |
||||
CORRADE_COMPARE(transformation[2].rotationScaling(), scaling); |
||||
|
||||
const auto capDistance = Vector3::zAxis(3.5f); |
||||
CORRADE_COMPARE(transformation[0].translation(), a+capDistance); |
||||
CORRADE_COMPARE(transformation[1].translation(), a+Vector3::zAxis(2.0f)); |
||||
CORRADE_COMPARE(transformation[2].translation(), b-capDistance); |
||||
} |
||||
|
||||
void CapsuleRendererTest::antiParallel3D() { |
||||
const Vector3 a(0.5f, 3.0f, 7.0f); |
||||
const Vector3 b(0.5f, 3.0f, 3.0f); |
||||
std::array<Matrix4, 3> transformation = Implementation::capsuleRendererTransformation<3>(a, b, 3.5f); |
||||
|
||||
const auto rotation = Matrix4::rotationX(-Deg(90.0f)); |
||||
const auto rotationScaling = (rotation*Matrix4::scaling(Vector3(3.5f))).rotationScaling(); |
||||
CORRADE_COMPARE(transformation[0].rotationScaling(), rotationScaling); |
||||
CORRADE_COMPARE(transformation[1].rotationScaling(), |
||||
(rotation*Matrix4::scaling({3.5f, 2.0f, 3.5f})).rotationScaling()); |
||||
CORRADE_COMPARE(transformation[2].rotationScaling(), rotationScaling); |
||||
|
||||
const auto capDistance = Vector3::zAxis(-3.5f); |
||||
CORRADE_COMPARE(transformation[0].translation(), a+capDistance); |
||||
CORRADE_COMPARE(transformation[1].translation(), a+Vector3::zAxis(-2.0f)); |
||||
CORRADE_COMPARE(transformation[2].translation(), b-capDistance); |
||||
} |
||||
|
||||
void CapsuleRendererTest::common3D() { |
||||
const Vector3 a(0.5f, 3.0f, 7.0f); |
||||
const Vector3 b(7.5f, -1.0f, 1.5f); |
||||
std::array<Matrix4, 3> transformation = Implementation::capsuleRendererTransformation<3>(a, b, 3.5f); |
||||
|
||||
/* Vector from capsule center to top hemisphere center */ |
||||
const Vector3 up(3.5f, -2.0f, -2.75f); |
||||
CORRADE_COMPARE(transformation[0].up(), up.resized(3.5f)); |
||||
CORRADE_COMPARE(transformation[1].up(), up); |
||||
CORRADE_COMPARE(transformation[2].up(), up.resized(3.5f)); |
||||
|
||||
const auto right = Vector3(-2.0f, -3.5f, 0.0f).resized(3.5f); |
||||
CORRADE_COMPARE(transformation[0].right(), right); |
||||
CORRADE_COMPARE(transformation[1].right(), right); |
||||
CORRADE_COMPARE(transformation[2].right(), right); |
||||
|
||||
const auto backward = Vector3(9.625f, -5.5f, 16.25f).resized(3.5f); |
||||
CORRADE_COMPARE(transformation[0].backward(), backward); |
||||
CORRADE_COMPARE(transformation[1].backward(), backward); |
||||
CORRADE_COMPARE(transformation[2].backward(), backward); |
||||
|
||||
/* Orthogonality */ |
||||
CORRADE_COMPARE(Vector3::dot(transformation[0].up(), transformation[0].right()), 0.0f); |
||||
CORRADE_COMPARE(Vector3::dot(transformation[0].up(), transformation[0].backward()), 0.0f); |
||||
CORRADE_COMPARE(Vector3::dot(transformation[0].right(), transformation[0].backward()), 0.0f); |
||||
|
||||
const Vector3 capDistance = up.resized(3.5f); |
||||
CORRADE_COMPARE(transformation[0].translation(), a+capDistance); |
||||
CORRADE_COMPARE(transformation[1].translation(), 0.5f*(a + b)); |
||||
CORRADE_COMPARE(transformation[2].translation(), b-capDistance); |
||||
} |
||||
|
||||
}}} |
||||
|
||||
CORRADE_TEST_MAIN(Magnum::DebugTools::Test::CapsuleRendererTest) |
||||
@ -0,0 +1,125 @@
|
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#include <TestSuite/Tester.h> |
||||
|
||||
#include "DebugTools/Implementation/CylinderRendererTransformation.h" |
||||
|
||||
namespace Magnum { namespace DebugTools { namespace Test { |
||||
|
||||
class CylinderRendererTest: public TestSuite::Tester { |
||||
public: |
||||
explicit CylinderRendererTest(); |
||||
|
||||
void zeroLength2D(); |
||||
void common2D(); |
||||
|
||||
void zeroLength3D(); |
||||
void parallel3D(); |
||||
void antiParallel3D(); |
||||
void common3D(); |
||||
}; |
||||
|
||||
CylinderRendererTest::CylinderRendererTest() { |
||||
addTests({&CylinderRendererTest::zeroLength2D, |
||||
&CylinderRendererTest::common2D, |
||||
|
||||
&CylinderRendererTest::zeroLength3D, |
||||
&CylinderRendererTest::parallel3D, |
||||
&CylinderRendererTest::antiParallel3D, |
||||
&CylinderRendererTest::common3D}); |
||||
} |
||||
|
||||
void CylinderRendererTest::zeroLength2D() { |
||||
const Vector2 a(0.5f, 3.0f); |
||||
const Matrix3 transformation = Implementation::cylinderRendererTransformation<2>(a, a, 3.5f); |
||||
|
||||
CORRADE_COMPARE(transformation.rotationScaling(), (Math::Matrix<2, Float>::fromDiagonal({3.5f, 0.0f}))); |
||||
CORRADE_COMPARE(transformation.translation(), a); |
||||
} |
||||
|
||||
void CylinderRendererTest::common2D() { |
||||
const Vector2 a(0.5f, 3.0f); |
||||
const Vector2 b(7.5f, -1.0f); |
||||
const Matrix3 transformation = Implementation::cylinderRendererTransformation<2>(a, b, 3.5f); |
||||
|
||||
/* Rotation + scaling, test orthogonality */ |
||||
CORRADE_COMPARE(transformation.up(), Vector2(3.5f, -2.0f)); |
||||
CORRADE_COMPARE(transformation.right(), Vector2(4.0f, 7.0f).resized(3.5f)); |
||||
CORRADE_COMPARE(Vector2::dot(transformation.up(), transformation.right()), 0.0f); |
||||
|
||||
CORRADE_COMPARE(transformation.translation(), 0.5f*(a + b)); |
||||
} |
||||
|
||||
void CylinderRendererTest::zeroLength3D() { |
||||
const Vector3 a(0.5f, 3.0f, 7.0f); |
||||
const Matrix4 transformation = Implementation::cylinderRendererTransformation<3>(a, a, 3.5f); |
||||
|
||||
CORRADE_COMPARE(transformation.rotationScaling(), (Math::Matrix<3, Float>::fromDiagonal({3.5f, 0.0f, 3.5f}))); |
||||
CORRADE_COMPARE(transformation.translation(), a); |
||||
} |
||||
|
||||
void CylinderRendererTest::parallel3D() { |
||||
const Vector3 a(0.5f, 3.0f, 7.0f); |
||||
const Vector3 b(0.5f, 3.0f, 11.0f); |
||||
const Matrix4 transformation = Implementation::cylinderRendererTransformation<3>(a, b, 3.5f); |
||||
|
||||
CORRADE_COMPARE(transformation.rotationScaling(), |
||||
(Matrix4::rotationX(Deg(90.0f))*Matrix4::scaling({3.5f, 2.0f, 3.5f})).rotationScaling()); |
||||
|
||||
CORRADE_COMPARE(transformation.translation(), a+Vector3::zAxis(2.0f)); |
||||
} |
||||
|
||||
void CylinderRendererTest::antiParallel3D() { |
||||
const Vector3 a(0.5f, 3.0f, 7.0f); |
||||
const Vector3 b(0.5f, 3.0f, 3.0f); |
||||
const Matrix4 transformation = Implementation::cylinderRendererTransformation<3>(a, b, 3.5f); |
||||
|
||||
CORRADE_COMPARE(transformation.rotationScaling(), |
||||
(Matrix4::rotationX(-Deg(90.0f))*Matrix4::scaling({3.5f, 2.0f, 3.5f})).rotationScaling()); |
||||
|
||||
CORRADE_COMPARE(transformation.translation(), a+Vector3::zAxis(-2.0f)); |
||||
} |
||||
|
||||
void CylinderRendererTest::common3D() { |
||||
const Vector3 a(0.5f, 3.0f, 7.0f); |
||||
const Vector3 b(7.5f, -1.0f, 1.5f); |
||||
const Matrix4 transformation = Implementation::cylinderRendererTransformation<3>(a, b, 3.5f); |
||||
|
||||
/* Rotation + scaling */ |
||||
CORRADE_COMPARE(transformation.up(), Vector3(3.5f, -2.0f, -2.75f)); |
||||
CORRADE_COMPARE(transformation.right(), Vector3(-2.0f, -3.5f, 0.0f).resized(3.5f)); |
||||
CORRADE_COMPARE(transformation.backward(), Vector3(9.625f, -5.5f, 16.25f).resized(3.5f)); |
||||
|
||||
/* Orthogonality */ |
||||
CORRADE_COMPARE(Vector3::dot(transformation.up(), transformation.right()), 0.0f); |
||||
CORRADE_COMPARE(Vector3::dot(transformation.up(), transformation.backward()), 0.0f); |
||||
CORRADE_COMPARE(Vector3::dot(transformation.right(), transformation.backward()), 0.0f); |
||||
|
||||
CORRADE_COMPARE(transformation.translation(), 0.5f*(a + b)); |
||||
} |
||||
|
||||
}}} |
||||
|
||||
CORRADE_TEST_MAIN(Magnum::DebugTools::Test::CylinderRendererTest) |
||||
@ -0,0 +1,43 @@
|
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#include "MeshView.h" |
||||
|
||||
#include "Mesh.h" |
||||
|
||||
namespace Magnum { |
||||
|
||||
MeshView& MeshView::setIndexRange(Int first, Int count, UnsignedInt start, UnsignedInt end) { |
||||
_indexOffset = first*_original->indexSize(); |
||||
_indexCount = count; |
||||
_indexStart = start; |
||||
_indexEnd = end; |
||||
return *this; |
||||
} |
||||
|
||||
void MeshView::draw() { |
||||
_original->drawInternal(_firstVertex, _vertexCount, _indexOffset, _indexCount, _indexStart, _indexEnd); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,139 @@
|
||||
#ifndef Magnum_MeshView_h |
||||
#define Magnum_MeshView_h |
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
/** @file
|
||||
* @brief Class Magnum::MeshView |
||||
*/ |
||||
|
||||
#include "Magnum.h" |
||||
#include "magnumVisibility.h" |
||||
|
||||
#ifndef DOXYGEN_GENERATING_OUTPUT |
||||
typedef std::ptrdiff_t GLintptr; |
||||
#endif |
||||
|
||||
namespace Magnum { |
||||
|
||||
/**
|
||||
@brief %Mesh view |
||||
|
||||
Allows different interpretation of given @ref Mesh data via different vertex or |
||||
index count and offset. It is then possible to reuse one mesh buffer |
||||
configuration for different views. %Mesh primitive, index type, attribute |
||||
bindings and attached buffers are reused from original mesh. |
||||
|
||||
The same rules as in Mesh apply, i.e. if the view has non-zero index count, it |
||||
is treated as indexed mesh, otherwise it is treated as non-indexed mesh. If |
||||
both index and vertex count is zero, the view is treated as empty and no draw |
||||
commands are issued when calling draw(). |
||||
|
||||
You must ensure that the original mesh remains available for whole view |
||||
lifetime. |
||||
@todo Might cause issues when there are more data than just indices in index |
||||
buffer (wrongly computed offset) |
||||
*/ |
||||
class MAGNUM_EXPORT MeshView { |
||||
public: |
||||
/**
|
||||
* @brief Constructor |
||||
* @param original Original, already configured mesh |
||||
*/ |
||||
explicit MeshView(Mesh& original); |
||||
|
||||
/** @brief Copy constructor */ |
||||
MeshView(const MeshView& other) = default; |
||||
|
||||
/** @brief Movement is not allowed */ |
||||
MeshView(MeshView&& other) = delete; |
||||
|
||||
/** @brief Copy assignment */ |
||||
MeshView& operator=(const MeshView&) = default; |
||||
|
||||
/** @brief Movement is not allowed */ |
||||
MeshView& operator=(MeshView&& other) = delete; |
||||
|
||||
/**
|
||||
* @brief Set vertex range |
||||
* @param first First vertex |
||||
* @param count Vertex count |
||||
* @return Reference to self (for method chaining) |
||||
* |
||||
* Default is zero @p offset and zero @p count. If index range is |
||||
* non-zero, vertex range is ignored, see main class documentation for |
||||
* more information. |
||||
*/ |
||||
MeshView& setVertexRange(Int first, Int count) { |
||||
_firstVertex = first; |
||||
_vertexCount = count; |
||||
return *this; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Set index range |
||||
* @param first First index |
||||
* @param count Index count |
||||
* @param start Minimum array index contained in the buffer |
||||
* @param end Maximum array index contained in the buffer |
||||
* @return Reference to self (for method chaining) |
||||
* |
||||
* Specifying `0` for both @p start and @p end behaves the same as |
||||
* @ref setIndexRange(Int, Int). |
||||
*/ |
||||
MeshView& setIndexRange(Int first, Int count, UnsignedInt start, UnsignedInt end); |
||||
|
||||
/**
|
||||
* @brief Set index range |
||||
* @param first First index |
||||
* @param count Index count |
||||
* @return Reference to self (for method chaining) |
||||
* |
||||
* Prefer to use @ref setIndexRange(Int, Int, UnsignedInt, UnsignedInt) |
||||
* for better performance. |
||||
*/ |
||||
MeshView& setIndexRange(Int first, Int count) { |
||||
return setIndexRange(first, count, 0, 0); |
||||
} |
||||
|
||||
/**
|
||||
* @brief Draw the mesh |
||||
* |
||||
* See @ref Mesh::draw() for more information. |
||||
*/ |
||||
void draw(); |
||||
|
||||
private: |
||||
Mesh* _original; |
||||
|
||||
Int _firstVertex, _vertexCount, _indexCount; |
||||
GLintptr _indexOffset; |
||||
UnsignedInt _indexStart, _indexEnd; |
||||
}; |
||||
|
||||
inline MeshView::MeshView(Mesh& original): _original(&original), _firstVertex(0), _vertexCount(0), _indexCount(0), _indexOffset(0), _indexStart(0), _indexEnd(0) {} |
||||
|
||||
} |
||||
|
||||
#endif |
||||
@ -0,0 +1,58 @@
|
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#include "Cylinder.h" |
||||
|
||||
#include "Math/Functions.h" |
||||
#include "Math/Matrix3.h" |
||||
#include "Math/Matrix4.h" |
||||
#include "Math/Geometry/Distance.h" |
||||
#include "Magnum.h" |
||||
#include "Shapes/Point.h" |
||||
#include "Shapes/Sphere.h" |
||||
|
||||
using namespace Magnum::Math::Geometry; |
||||
|
||||
namespace Magnum { namespace Shapes { |
||||
|
||||
template<UnsignedInt dimensions> Cylinder<dimensions> Cylinder<dimensions>::transformed(const typename DimensionTraits<dimensions, Float>::MatrixType& matrix) const { |
||||
return Cylinder<dimensions>(matrix.transformPoint(_a), matrix.transformPoint(_b), matrix.uniformScaling()*_radius); |
||||
} |
||||
|
||||
template<UnsignedInt dimensions> bool Cylinder<dimensions>::operator%(const Point<dimensions>& other) const { |
||||
return Distance::linePointSquared(_a, _b, other.position()) < |
||||
Math::pow<2>(_radius); |
||||
} |
||||
|
||||
template<UnsignedInt dimensions> bool Cylinder<dimensions>::operator%(const Sphere<dimensions>& other) const { |
||||
return Distance::linePointSquared(_a, _b, other.position()) < |
||||
Math::pow<2>(_radius+other.radius()); |
||||
} |
||||
|
||||
#ifndef DOXYGEN_GENERATING_OUTPUT |
||||
template class MAGNUM_SHAPES_EXPORT Cylinder<2>; |
||||
template class MAGNUM_SHAPES_EXPORT Cylinder<3>; |
||||
#endif |
||||
|
||||
}} |
||||
@ -0,0 +1,117 @@
|
||||
#ifndef Magnum_Shapes_Cylinder_h |
||||
#define Magnum_Shapes_Cylinder_h |
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
/** @file
|
||||
* @brief Class Magnum::Shapes::Cylinder, typedef Magnum::Shapes::Cylinder2D, Magnum::Shapes::Cylinder3D |
||||
*/ |
||||
|
||||
#include "Math/Vector3.h" |
||||
#include "DimensionTraits.h" |
||||
#include "Shapes/Shapes.h" |
||||
#include "Shapes/magnumShapesVisibility.h" |
||||
|
||||
namespace Magnum { namespace Shapes { |
||||
|
||||
/**
|
||||
@brief Infinite cylinder defined by line and radius |
||||
|
||||
Unlike other elements the cylinder expects uniform scaling. See @ref shapes for |
||||
brief introduction. |
||||
@see @ref Cylinder2D, @ref Cylinder3D, @ref Capsule |
||||
@todo Store the radius as squared value to avoid sqrt/pow? Will complicate |
||||
collision detection with sphere. |
||||
*/ |
||||
template<UnsignedInt dimensions> class MAGNUM_SHAPES_EXPORT Cylinder { |
||||
public: |
||||
enum: UnsignedInt { |
||||
Dimensions = dimensions /**< Dimension count */ |
||||
}; |
||||
|
||||
/**
|
||||
* @brief Constructor |
||||
* |
||||
* Creates zero-sized cylinder at origin. |
||||
*/ |
||||
constexpr /*implicit*/ Cylinder(): _radius(0.0f) {} |
||||
|
||||
/** @brief Constructor */ |
||||
constexpr /*implicit*/ Cylinder(const typename DimensionTraits<dimensions, Float>::VectorType& a, const typename DimensionTraits<dimensions, Float>::VectorType& b, Float radius): _a(a), _b(b), _radius(radius) {} |
||||
|
||||
/** @brief Transformed shape */ |
||||
Cylinder<dimensions> transformed(const typename DimensionTraits<dimensions, Float>::MatrixType& matrix) const; |
||||
|
||||
/** @brief First point */ |
||||
constexpr typename DimensionTraits<dimensions, Float>::VectorType a() const { |
||||
return _a; |
||||
} |
||||
|
||||
/** @brief Set first point */ |
||||
void setA(const typename DimensionTraits<dimensions, Float>::VectorType& a) { |
||||
_a = a; |
||||
} |
||||
|
||||
/** @brief Second point */ |
||||
constexpr typename DimensionTraits<dimensions, Float>::VectorType b() const { |
||||
return _b; |
||||
} |
||||
|
||||
/** @brief Set second point */ |
||||
void setB(const typename DimensionTraits<dimensions, Float>::VectorType& b) { |
||||
_b = b; |
||||
} |
||||
|
||||
/** @brief Radius */ |
||||
constexpr Float radius() const { return _radius; } |
||||
|
||||
/** @brief Set radius */ |
||||
void setRadius(Float radius) { _radius = radius; } |
||||
|
||||
/** @brief Collision with point */ |
||||
bool operator%(const Point<dimensions>& other) const; |
||||
|
||||
/** @brief Collision with sphere */ |
||||
bool operator%(const Sphere<dimensions>& other) const; |
||||
|
||||
private: |
||||
typename DimensionTraits<dimensions, Float>::VectorType _a, _b; |
||||
Float _radius; |
||||
}; |
||||
|
||||
/** @brief Infinite two-dimensional cylinder */ |
||||
typedef Cylinder<2> Cylinder2D; |
||||
|
||||
/** @brief Infinite three-dimensional cylinder */ |
||||
typedef Cylinder<3> Cylinder3D; |
||||
|
||||
/** @collisionoperator{Point,Cylinder} */ |
||||
template<UnsignedInt dimensions> inline bool operator%(const Point<dimensions>& a, const Cylinder<dimensions>& b) { return b % a; } |
||||
|
||||
/** @collisionoperator{Sphere,Cylinder} */ |
||||
template<UnsignedInt dimensions> inline bool operator%(const Sphere<dimensions>& a, const Cylinder<dimensions>& b) { return b % a; } |
||||
|
||||
}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,85 @@
|
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#include "Math/Matrix3.h" |
||||
#include "Math/Matrix4.h" |
||||
#include "Magnum.h" |
||||
#include "Shapes/Cylinder.h" |
||||
#include "Shapes/Point.h" |
||||
#include "Shapes/Sphere.h" |
||||
|
||||
#include "ShapeTestBase.h" |
||||
|
||||
namespace Magnum { namespace Shapes { namespace Test { |
||||
|
||||
class CylinderTest: public TestSuite::Tester { |
||||
public: |
||||
CylinderTest(); |
||||
|
||||
void transformed(); |
||||
void transformedAverageScaling(); |
||||
void collisionPoint(); |
||||
void collisionSphere(); |
||||
}; |
||||
|
||||
CylinderTest::CylinderTest() { |
||||
addTests({&CylinderTest::transformed, |
||||
&CylinderTest::collisionPoint, |
||||
&CylinderTest::collisionSphere}); |
||||
} |
||||
|
||||
void CylinderTest::transformed() { |
||||
const Shapes::Cylinder3D cylinder({1.0f, 2.0f, 3.0f}, {-1.0f, -2.0f, -3.0f}, 7.0f); |
||||
|
||||
const auto transformed = cylinder.transformed(Matrix4::scaling(Vector3(2.0f))*Matrix4::rotation(Deg(90.0f), Vector3::zAxis())); |
||||
CORRADE_COMPARE(transformed.a(), Vector3(-4.0f, 2.0f, 6.0f)); |
||||
CORRADE_COMPARE(transformed.b(), Vector3(4.0f, -2.0f, -6.0f)); |
||||
CORRADE_COMPARE(transformed.radius(), 14.0f); |
||||
} |
||||
|
||||
void CylinderTest::collisionPoint() { |
||||
Shapes::Cylinder3D cylinder({-1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}, 2.0f); |
||||
Shapes::Point3D point({2.0f, 0.0f, 0.0f}); |
||||
Shapes::Point3D point1({1.0f, 3.1f, 0.0f}); |
||||
Shapes::Point3D point2({2.9f, -1.0f, 0.0f}); |
||||
|
||||
VERIFY_COLLIDES(cylinder, point); |
||||
VERIFY_COLLIDES(cylinder, point1); |
||||
VERIFY_NOT_COLLIDES(cylinder, point2); |
||||
} |
||||
|
||||
void CylinderTest::collisionSphere() { |
||||
Shapes::Cylinder3D cylinder({-1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}, 2.0f); |
||||
Shapes::Sphere3D sphere({3.0f, 0.0f, 0.0f}, 0.9f); |
||||
Shapes::Sphere3D sphere1({1.0f, 4.1f, 0.0f}, 1.0f); |
||||
Shapes::Sphere3D sphere2({3.5f, -1.0f, 0.0f}, 0.6f); |
||||
|
||||
VERIFY_COLLIDES(cylinder, sphere); |
||||
VERIFY_COLLIDES(cylinder, sphere1); |
||||
VERIFY_NOT_COLLIDES(cylinder, sphere2); |
||||
} |
||||
|
||||
}}} |
||||
|
||||
CORRADE_TEST_MAIN(Magnum::Shapes::Test::CylinderTest) |
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue