diff options
Diffstat (limited to 'o3d/core/cross/field.cc')
-rw-r--r-- | o3d/core/cross/field.cc | 618 |
1 files changed, 0 insertions, 618 deletions
diff --git a/o3d/core/cross/field.cc b/o3d/core/cross/field.cc deleted file mode 100644 index 0a31eff..0000000 --- a/o3d/core/cross/field.cc +++ /dev/null @@ -1,618 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the definitions for the Buffer, VertexBuffer and -// IndexBuffer. - -#include <vector> -#include "core/cross/field.h" -#include "core/cross/error.h" -#include "core/cross/buffer.h" -#include "core/cross/pointer_utils.h" -#include "core/cross/types.h" -#include "core/cross/renderer.h" -#include "import/cross/memory_stream.h" - -namespace o3d { - -O3D_DEFN_CLASS(Field, NamedObject); -O3D_DEFN_CLASS(FloatField, Field); -O3D_DEFN_CLASS(UInt32Field, Field); -O3D_DEFN_CLASS(UByteNField, Field); - -namespace { - -// Sets a field from a specific type of source converting through a -// convertFunction. -template <typename SourceType, - typename DestinationType, - DestinationType convert_function(SourceType value)> -void SetFrom(const SourceType* source, - unsigned source_stride, - Field* field, - unsigned destination_start_index, - unsigned num_elements) { - if (!field->RangeValid(destination_start_index, num_elements)) { - return; - } - - Buffer* buffer = field->buffer(); - o3d::BufferLockHelper helper(buffer); - void* buffer_data = helper.GetData(o3d::Buffer::WRITE_ONLY); - if (!buffer_data) { - O3D_ERROR(field->service_locator()) - << "could not lock buffer for field '" << field->name() << "'"; - return; - } - unsigned destination_stride = buffer->stride(); - unsigned num_components = field->num_components(); - DestinationType* destination = - PointerFromVoidPointer<DestinationType*>( - buffer_data, - destination_start_index * destination_stride + field->offset()); - for (; num_elements; --num_elements) { - for (unsigned cc = 0; cc < num_components; ++cc) { - destination[cc] = convert_function(source[cc]); - } - source += source_stride; - destination = AddPointerOffset(destination, destination_stride); - } -} - -template <typename SourceType, - typename DestinationType, - DestinationType convert_function(SourceType value)> -void SetFromWithSwizzle(const SourceType* source, - unsigned source_stride, - Field* field, - unsigned destination_start_index, - unsigned num_elements, - const int* swizzle_table) { - if (!field->RangeValid(destination_start_index, num_elements)) { - return; - } - - Buffer* buffer = field->buffer(); - o3d::BufferLockHelper helper(buffer); - void* buffer_data = helper.GetData(o3d::Buffer::WRITE_ONLY); - if (!buffer_data) { - O3D_ERROR(field->service_locator()) - << "could not lock buffer for field '" << field->name() << "'"; - return; - } - unsigned destination_stride = buffer->stride(); - unsigned num_components = field->num_components(); - DestinationType* destination = - PointerFromVoidPointer<DestinationType*>( - buffer_data, - destination_start_index * destination_stride + field->offset()); - for (; num_elements; --num_elements) { - for (unsigned cc = 0; cc < num_components; ++cc) { - destination[swizzle_table[cc]] = convert_function(source[cc]); - } - source += source_stride; - destination = AddPointerOffset(destination, destination_stride); - } -} - -// Gets a field copying into a specific type of destination converting through a -// convertFunction. -template <typename SourceType, - typename DestinationType, - DestinationType convert_function(SourceType value)> -void GetAs(const Field* field_c, - unsigned source_start_index, - DestinationType* destination, - unsigned destination_stride, - unsigned num_elements) { - Field* field = const_cast<Field*>(field_c); - if (!field->RangeValid(source_start_index, num_elements)) { - return; - } - - Buffer* buffer = field->buffer(); - o3d::BufferLockHelper helper(buffer); - void* buffer_data = helper.GetData(o3d::Buffer::READ_ONLY); - if (!buffer_data) { - O3D_ERROR(field->service_locator()) - << "could not lock buffer for field '" << field->name() << "'"; - return; - } - unsigned source_stride = buffer->stride(); - unsigned num_components = field->num_components(); - SourceType* source = PointerFromVoidPointer<SourceType*>( - buffer_data, - source_start_index * source_stride + field->offset()); - for (; num_elements; --num_elements) { - for (unsigned cc = 0; cc < num_components; ++cc) { - destination[cc] = convert_function(source[cc]); - } - source = AddPointerOffset(source, source_stride); - destination += destination_stride; - } -} - - -// Gets a field copying into a specific type of destination converting through a -// convertFunction. -template <typename SourceType, - typename DestinationType, - DestinationType convert_function(SourceType value)> -void GetAsWithSwizzle(const Field* field_c, - unsigned source_start_index, - DestinationType* destination, - unsigned destination_stride, - unsigned num_elements, - const int* swizzle_table) { - Field* field = const_cast<Field*>(field_c); - if (!field->RangeValid(source_start_index, num_elements)) { - return; - } - - Buffer* buffer = field->buffer(); - o3d::BufferLockHelper helper(buffer); - void* buffer_data = helper.GetData(o3d::Buffer::READ_ONLY); - if (!buffer_data) { - O3D_ERROR(field->service_locator()) - << "could not lock buffer for field '" << field->name() << "'"; - return; - } - unsigned source_stride = buffer->stride(); - unsigned num_components = field->num_components(); - SourceType* source = PointerFromVoidPointer<SourceType*>( - buffer_data, - source_start_index * source_stride + field->offset()); - for (; num_elements; --num_elements) { - for (unsigned cc = 0; cc < num_components; ++cc) { - destination[cc] = convert_function(source[swizzle_table[cc]]); - } - source = AddPointerOffset(source, source_stride); - destination += destination_stride; - } -} - -inline float ConvertFloatToFloat(float value) { - return value; -} - -// Note that |value| is an int here since we want to avoid loading -// an incorrectly swapped value into a float register -inline float ConvertLittleEndianFloatToFloat(uint32 value) { - union UInt32FloatUnion { - uint32 i; - float f; - }; - UInt32FloatUnion u; - u.i = MemoryReadStream::GetLittleEndianUInt32( - reinterpret_cast<uint32*>(&value)); - return u.f; -} - -inline uint32 ConvertLittleEndianUInt32ToUInt32(uint32 value) { - return MemoryReadStream::GetLittleEndianUInt32( - reinterpret_cast<uint32*>(&value)); -} - -inline float ConvertUInt32ToFloat(uint32 value) { - return static_cast<float>(value); -} - -inline float ConvertUByteNToFloat(uint8 value) { - return static_cast<float>(value) / 255.0f; -} - -inline uint32 ConvertFloatToUInt32(float value) { - return static_cast<uint32>(std::max(0.0f, value)); -} - -inline uint32 ConvertUInt32ToUInt32(uint32 value) { - return value; -} - -inline uint32 ConvertUByteNToUInt32(uint8 value) { - return static_cast<uint32>(value > 0); -} - -inline uint8 ConvertFloatToUByteN(float value) { - return static_cast<uint8>(floorf( - std::min(1.0f, std::max(0.0f, value)) * 255.0f + 0.5f)); -} - -inline uint8 ConvertUInt32ToUByteN(uint32 value) { - return static_cast<uint8>(std::min<unsigned>(255, value)); -} - -inline uint8 ConvertUByteNToUByteN(uint8 value) { - return value; -} - -} // anonymous namespace. - -Field::Field(ServiceLocator* service_locator, - Buffer* buffer, - unsigned num_components, - unsigned offset) - : NamedObject(service_locator), - buffer_(buffer), - num_components_(num_components), - offset_(offset) { - DCHECK(num_components > 0); -} - -bool Field::RangeValid(unsigned int start_index, unsigned int num_elements) { - if (!buffer_) { - O3D_ERROR(service_locator()) - << "The buffer for field '" << name() << "' no longer exists"; - return false; - } - if (start_index + num_elements > buffer_->num_elements() || - start_index + num_elements < start_index) { - O3D_ERROR(service_locator()) - << "Range is not valid for Buffer '"<< buffer_->name() - << "' on Field '" << name() << "'"; - return false; - } - return true; -} - -void Field::Copy(const Field& source) { - if (!source.IsA(GetClass())) { - O3D_ERROR(service_locator()) - << "source field of type " << source.GetClassName() - << " is not compatible with field of type " << GetClassName(); - return; - } - if (!source.buffer()) { - O3D_ERROR(service_locator()) << "source buffer is null"; - return; - } - if (!buffer()) { - O3D_ERROR(service_locator()) << "destination buffer is null"; - return; - } - ConcreteCopy(source); -} - -// FloatField ------------------- - -FloatField::FloatField(ServiceLocator* service_locator, - Buffer* buffer, - unsigned num_components, - unsigned offset) - : Field(service_locator, buffer, num_components, offset) { -} - -size_t FloatField::GetFieldComponentSize() const { - return sizeof(float); // NOLINT -} - -void FloatField::SetFromFloats(const float* source, - unsigned source_stride, - unsigned destination_start_index, - unsigned num_elements) { - SetFrom<const float, float, ConvertFloatToFloat>( - source, source_stride, this, destination_start_index, num_elements); -} - -void FloatField::SetFromUInt32s(const uint32* source, - unsigned source_stride, - unsigned destination_start_index, - unsigned num_elements) { - SetFrom<const uint32, float, ConvertUInt32ToFloat>( - source, source_stride, this, destination_start_index, num_elements); -} - -void FloatField::SetFromUByteNs(const uint8* source, - unsigned source_stride, - unsigned destination_start_index, - unsigned num_elements) { - SetFrom<const uint8, float, ConvertUByteNToFloat>( - source, source_stride, this, destination_start_index, num_elements); -} - -bool FloatField::SetFromMemoryStream(MemoryReadStream* stream) { - if (!buffer()) { - O3D_ERROR(service_locator()) - << "The buffer for field '" << name() << "' no longer exists"; - return false; - } - - size_t num_elements = buffer()->num_elements(); - - // sanity check that the stream has enough data - if (stream->GetRemainingByteCount() < num_elements * size()) { - return false; - } - - // Note that we're interpreting the source as uint32 since that's - // what ConvertLittleEndianFloatToFloat wants (byte swapping for - // float32 and uint32 are the same). Interpreting floating point - // values before they're byte-swapped can cause problems... - const uint32 *source = stream->GetDirectMemoryPointerAs<const uint32>(); - - stream->Skip(num_elements * size()); - - SetFrom<const uint32, float, ConvertLittleEndianFloatToFloat>( - source, num_components(), this, 0, num_elements); - - return true; -} - -void FloatField::GetAsFloats(unsigned source_start_index, - float* destination, - unsigned destination_stride, - unsigned num_elements) const { - GetAs<const float, float, ConvertFloatToFloat>( - this, - source_start_index, - destination, - destination_stride, - num_elements); -} - -void FloatField::ConcreteCopy(const Field& source) { - DCHECK(source.IsA(GetClass())); - DCHECK(source.buffer()); - unsigned num_components = source.num_components(); - unsigned num_elements = source.buffer()->num_elements(); - scoped_array<float> temp(new float[num_components * num_elements]); - source.GetAsFloats(0, temp.get(), num_components, num_elements); - SetFromFloats(temp.get(), num_components, 0, num_elements); -} - -Field::Ref FloatField::Create(ServiceLocator* service_locator, - Buffer* buffer, - unsigned num_components, - unsigned offset) { - return Field::Ref( - new FloatField(service_locator, buffer, num_components, offset)); -} - -// UInt32Field ------------------- - -UInt32Field::UInt32Field(ServiceLocator* service_locator, - Buffer* buffer, - unsigned num_components, - unsigned offset) - : Field(service_locator, buffer, num_components, offset) { -} - -size_t UInt32Field::GetFieldComponentSize() const { - return sizeof(uint32); // NOLINT -} - -void UInt32Field::SetFromFloats(const float* source, - unsigned source_stride, - unsigned destination_start_index, - unsigned num_elements) { - SetFrom<const float, uint32, ConvertFloatToUInt32>( - source, source_stride, this, destination_start_index, num_elements); -} - -void UInt32Field::SetFromUInt32s(const uint32* source, - unsigned source_stride, - unsigned destination_start_index, - unsigned num_elements) { - SetFrom<const uint32, uint32, ConvertUInt32ToUInt32>( - source, source_stride, this, destination_start_index, num_elements); -} - -void UInt32Field::SetFromUByteNs(const uint8* source, - unsigned source_stride, - unsigned destination_start_index, - unsigned num_elements) { - SetFrom<const uint8, uint32, ConvertUByteNToUInt32>( - source, source_stride, this, destination_start_index, num_elements); -} - -bool UInt32Field::SetFromMemoryStream(MemoryReadStream* stream) { - if (!buffer()) { - O3D_ERROR(service_locator()) - << "The buffer for field '" << name() << "' no longer exists"; - return false; - } - - size_t num_elements = buffer()->num_elements(); - - // sanity check that the stream has enough data - if (stream->GetRemainingByteCount() < num_elements * size()) { - return false; - } - - const uint32 *source = stream->GetDirectMemoryPointerAs<const uint32>(); - - stream->Skip(num_elements * size()); - - SetFrom<const uint32, uint32, ConvertLittleEndianUInt32ToUInt32>( - source, num_components(), this, 0, num_elements); - - return true; -} - -void UInt32Field::GetAsFloats(unsigned source_start_index, - float* destination, - unsigned destination_stride, - unsigned num_elements) const { - GetAs<const uint32, float, ConvertUInt32ToFloat>( - this, - source_start_index, - destination, - destination_stride, - num_elements); -} - -void UInt32Field::GetAsUInt32s(unsigned source_start_index, - uint32* destination, - unsigned destination_stride, - unsigned num_elements) const { - GetAs<const uint32, uint32, ConvertUInt32ToUInt32>( - this, - source_start_index, - destination, - destination_stride, - num_elements); -} - -void UInt32Field::ConcreteCopy(const Field& source) { - DCHECK(source.IsA(GetClass())); - DCHECK(source.buffer()); - unsigned num_components = source.num_components(); - unsigned num_elements = source.buffer()->num_elements(); - scoped_array<uint32> temp(new uint32[num_components * num_elements]); - down_cast<const UInt32Field*>(&source)->GetAsUInt32s( - 0, temp.get(), num_components, num_elements); - SetFromUInt32s(temp.get(), num_components, 0, num_elements); -} - -Field::Ref UInt32Field::Create(ServiceLocator* service_locator, - Buffer* buffer, - unsigned num_components, - unsigned offset) { - return Field::Ref( - new UInt32Field(service_locator, buffer, num_components, offset)); -} - -// UByteNField ------------------- - -UByteNField::UByteNField(ServiceLocator* service_locator, - Buffer* buffer, - unsigned num_components, - unsigned offset) - : Field(service_locator, buffer, num_components, offset) { - Renderer* renderer = service_locator->GetService<Renderer>(); - DCHECK(renderer); - DCHECK(num_components % 4 == 0); - - swizzle_table_ = renderer->GetRGBAUByteNSwizzleTable(); -} - -size_t UByteNField::GetFieldComponentSize() const { - return sizeof(uint8); // NOLINT -} - -void UByteNField::SetFromFloats(const float* source, - unsigned source_stride, - unsigned destination_start_index, - unsigned num_elements) { - SetFromWithSwizzle<const float, uint8, ConvertFloatToUByteN>( - source, source_stride, this, destination_start_index, num_elements, - swizzle_table_); -} - -void UByteNField::SetFromUInt32s(const uint32* source, - unsigned source_stride, - unsigned destination_start_index, - unsigned num_elements) { - SetFromWithSwizzle<const uint32, uint8, ConvertUInt32ToUByteN>( - source, source_stride, this, destination_start_index, num_elements, - swizzle_table_); -} - -void UByteNField::SetFromUByteNs(const uint8* source, - unsigned source_stride, - unsigned destination_start_index, - unsigned num_elements) { - SetFromWithSwizzle<const uint8, uint8, ConvertUByteNToUByteN>( - source, source_stride, this, destination_start_index, num_elements, - swizzle_table_); -} - -bool UByteNField::SetFromMemoryStream(MemoryReadStream* stream) { - if (!buffer()) { - O3D_ERROR(service_locator()) - << "The buffer for field '" << name() << "' no longer exists"; - return false; - } - - size_t num_elements = buffer()->num_elements(); - - // sanity check that the stream has enough data - if (stream->GetRemainingByteCount() < num_elements * size()) { - return false; - } - - const uint8 *source = stream->GetDirectMemoryPointerAs<const uint8>(); - stream->Skip(num_elements * size()); - - SetFromWithSwizzle<const uint8, uint8, ConvertUByteNToUByteN>( - source, num_components(), this, 0, num_elements, swizzle_table_); - - return true; -} - -void UByteNField::GetAsFloats(unsigned source_start_index, - float* destination, - unsigned destination_stride, - unsigned num_elements) const { - GetAsWithSwizzle<const uint8, float, ConvertUByteNToFloat>( - this, - source_start_index, - destination, - destination_stride, - num_elements, - swizzle_table_); -} - -void UByteNField::GetAsUByteNs(unsigned source_start_index, - uint8* destination, - unsigned destination_stride, - unsigned num_elements) const { - GetAsWithSwizzle<const uint8, uint8, ConvertUByteNToUByteN>( - this, - source_start_index, - destination, - destination_stride, - num_elements, - swizzle_table_); -} - -void UByteNField::ConcreteCopy(const Field& source) { - DCHECK(source.IsA(GetClass())); - DCHECK(source.buffer()); - unsigned num_components = source.num_components(); - unsigned num_elements = source.buffer()->num_elements(); - scoped_array<uint8> temp(new uint8[num_components * num_elements]); - down_cast<const UByteNField*>(&source)->GetAsUByteNs( - 0, temp.get(), num_components, num_elements); - SetFromUByteNs(temp.get(), num_components, 0, num_elements); -} - - -Field::Ref UByteNField::Create(ServiceLocator* service_locator, - Buffer* buffer, - unsigned num_components, - unsigned offset) { - return Field::Ref( - new UByteNField(service_locator, buffer, num_components, offset)); -} - -} // namespace o3d |