// Copyright (c) 2020-2021, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto.  Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
//
#pragma once

#include <carb/Defines.h>
#include <carb/Types.h>

namespace carb
{

namespace fastcache
{

struct Float4x4
{
    float m[16];
};

struct Double4x4
{
    double m[16];
};

// NOTE: omni physics relies on this struct being all floats.
// Actual fastcache users should use Transformd defined below.
struct Transform
{
    carb::Float3 position;
    carb::Float4 orientation;
    carb::Float3 scale;
};

struct TransformD
{
    TransformD() {}
    explicit TransformD(const Transform& t) : orientation(t.orientation), scale(t.scale) {
        position.x = t.position.x;
        position.y = t.position.y;
        position.z = t.position.z;
    }
    void CopyTo(Transform& t)
    {
        t.position.x = float(position.x);
        t.position.y = float(position.y);
        t.position.z = float(position.z);
        t.orientation = orientation;
        t.scale = scale;
    }
    carb::Double3 position;
    carb::Float4 orientation;
    carb::Float3 scale;
};

// This type can be casted to carb::scenerenderer::VertexElemDesc
struct BufferDesc
{
    BufferDesc() = default;
    BufferDesc(const void* _data, uint32_t _elementStride, uint32_t _elementSize)
        : data(_data), elementStride(_elementStride), elementSize(_elementSize)
    {
    }
    const void* data = nullptr; // float elements, vec2, vec3 or vec4
    uint32_t elementStride = 0; // in bytes
    uint32_t elementSize = 0; // in bytes
};

typedef uint32_t FastCacheDirtyFlags;

const FastCacheDirtyFlags kFastCacheClean = 0; // only copy data to fast cache
const FastCacheDirtyFlags kFastCacheDirtyTransformRender = 1 << 1; // do we write transform to hydra render sync?
const FastCacheDirtyFlags kFastCacheDirtyTransformScale = 1 << 2; // change scale? false if rigid transform only
const FastCacheDirtyFlags kFastCacheDirtyTransformChildren = 1 << 3; // update all the children?
const FastCacheDirtyFlags kFastCacheDirtyPoints = 1 << 4; // mesh point data dirtied?
const FastCacheDirtyFlags kFastCacheDirtyNormals = 1 << 5; // mesh normal data dirtied?
const FastCacheDirtyFlags kFastCacheDirtyAll = ~0;

// cannot use USD data types in header, so we cast them to void pointer
typedef void* UsdPrimPtr;

} // namespace fastcache
} // namespace carb
