packages feed

lambdacube-engine-0.1.1: Graphics/LambdaCube/Mesh.hs

module Graphics.LambdaCube.Mesh where

import Data.Map (Map)
import qualified Data.Map as Map

import Graphics.LambdaCube.Types
import Graphics.LambdaCube.RenderOperation
import Graphics.LambdaCube.HardwareBuffer
import Graphics.LambdaCube.HardwareVertexBuffer
import Graphics.LambdaCube.HardwareIndexBuffer
import Graphics.LambdaCube.VertexIndexData

data (HardwareVertexBuffer vb, HardwareIndexBuffer ib) => SubMesh vb ib
    = SubMesh
    { smOperationType       :: OperationType            -- ^ The render operation type used to render this submesh

    {-| Dedicated vertex data (only valid if useSharedVertices = false).
        @remarks
            This data is completely owned by this submesh.
        @par
            The use of shared or non-shared buffers is determined when
            model data is converted to the OGRE .mesh format.
    -}
    , smVertexData          :: Maybe (VertexData vb)    -- ^ Indicates if this submesh shares vertex data with other meshes or whether it has it's own vertices.    
    , smIndexData           :: Maybe (IndexData ib)     -- ^ Face index data

    {-| Dedicated index map for translate blend index to bone index (only valid if useSharedVertices = false).
        @remarks
            This data is completely owned by this submesh.
        @par
            We collect actually used bones of all bone assignments, and build the
            blend index in 'packed' form, then the range of the blend index in vertex
            data VES_BLEND_INDICES element is continuous, with no gaps. Thus, by
            minimising the world matrix array constants passing to GPU, we can support
            more bones for a mesh when hardware skinning is used. The hardware skinning
            support limit is applied to each set of vertex data in the mesh, in other words, the
            hardware skinning support limit is applied only to the actually used bones of each
            SubMeshes, not all bones across the entire Mesh.
        @par
            Because the blend index is different to the bone index, therefore, we use
            the index map to translate the blend index to bone index.
        @par
            The use of shared or non-shared index map is determined when
            model data is converted to the OGRE .mesh format.
    -}
    --typedef vector<unsigned short>::type IndexMap;
    --IndexMap blendIndexToBoneIndexMap;

    --ProgressiveMesh::LODFaceList mLodFaceList;

    {-| A list of extreme points on the submesh (optional).
        @remarks
            These points are some arbitrary points on the mesh that are used
            by engine to better sort submeshes by depth. This doesn't matter
            much for non-transparent submeshes, as Z-buffer takes care of invisible
            surface culling anyway, but is pretty useful for semi-transparent
            submeshes because the order in which transparent submeshes must be
            rendered cannot be always correctly deduced from entity position.
        @par
            These points are intelligently chosen from the points that make up
            the submesh, the criteria for choosing them should be that these points
            somewhat characterize the submesh outline, e.g. they should not be
            close to each other, and they should be on the outer hull of the submesh.
            They can be stored in the .mesh file, or generated at runtime
            (see generateExtremes ()).
        @par
            If this array is empty, submesh sorting is done like in older versions -
            by comparing the positions of the owning entity.
    -}
    , smExtremityPoints     :: [FloatType3]
    , smMaterialName        :: String           -- ^ Name of the material this SubMesh uses.

        -- | Is there a material yet?
--        bool mMatInitialised;

        -- | paired list of texture aliases and texture names
--        AliasTextureNamePairList mTextureAliases;

--        VertexBoneAssignmentList mBoneAssignments;

        -- | Flag indicating that bone assignments need to be recompiled
--        bool mBoneAssignmentsOutOfDate;

		-- | Type of vertex animation for dedicated vertex data (populated by Mesh)
--		mutable VertexAnimationType mVertexAnimationType;

		-- | Is Build Edges Enabled
--		bool mBuildEdgesEnabled;
    }

data (HardwareVertexBuffer vb, HardwareIndexBuffer ib) => Mesh vb ib
    = Mesh
    { msSubMeshList                 :: [SubMesh vb ib]
    {-| A hashmap used to store optional SubMesh names.
    	Translates a name into SubMesh index
    -}
--typedef HashMap<String, ushort> SubMeshNameMap ;


--ected:

--DataStreamPtr mFreshFromDisk;

--SubMeshNameMap mSubMeshNameMap ;
    , msSubMeshNameMap              :: Map String Int

    -- | Local bounding box volume
    -- TODO: AxisAlignedBox mAABB;
    ---- | Local bounding sphere radius (centered on object)
    , msBoundRadius                 :: FloatType

    -- | Optional linked skeleton
    , msSkeletonName                :: String
-- TODO:    , msSkeleton            :: Skeleton


-- TODO: VertexBoneAssignmentList mBoneAssignments;

-- | Flag indicating that bone assignments need to be recompiled
-- TODO: bool mBoneAssignmentsOutOfDate;

-- TODO: const LodStrategy *mLodStrategy;
-- TODO: bool mIsLodManual;
-- TODO: ushort mNumLods;
-- TODO: MeshLodUsageList mMeshLodUsageList;

    , msVertexBufferUsage           :: Usage
    , msIndexBufferUsage            :: Usage
    , msVertexBufferShadowBuffer    :: Bool
    , msIndexBufferShadowBuffer     :: Bool


-- TODO: bool mPreparedForShadowVolumes;
-- TODO: bool mEdgeListsBuilt;
-- TODO: bool mAutoBuildEdgeLists;

-- | Storage of morph animations, lookup by name
-- TODO: typedef map<String, Animation*>::type AnimationList;
-- TODO: AnimationList mAnimationsList;
-- | The vertex animation type associated with the shared vertex data
-- TODO: mutable VertexAnimationType mSharedVertexDataAnimationType;
-- | Do we need to scan animations for animation types?
-- TODO: mutable bool mAnimationTypesDirty;

-- | List of available poses for shared and dedicated geometryPoseList
-- TODO: PoseList mPoseList;

{-| Shared vertex data.
    @remarks
        This vertex data can be shared among multiple submeshes. SubMeshes may not have
        their own VertexData, they may share this one.
    @par
        The use of shared or non-shared buffers is determined when
        model data is converted to the OGRE .mesh format.
-}
    , msSharedVertexData            :: Maybe (VertexData vb)

{-| Shared index map for translating blend index to bone index.
    @remarks
        This index map can be shared among multiple submeshes. SubMeshes might not have
        their own IndexMap, they might share this one.
    @par
        We collect actually used bones of all bone assignments, and build the
        blend index in 'packed' form, then the range of the blend index in vertex
        data VES_BLEND_INDICES element is continuous, with no gaps. Thus, by
        minimising the world matrix array constants passing to GPU, we can support
        more bones for a mesh when hardware skinning is used. The hardware skinning
        support limit is applied to each set of vertex data in the mesh, in other words, the
        hardware skinning support limit is applied only to the actually used bones of each
        SubMeshes, not all bones across the entire Mesh.
    @par
        Because the blend index is different to the bone index, therefore, we use
        the index map to translate the blend index to bone index.
    @par
        The use of shared or non-shared index map is determined when
        model data is converted to the OGRE .mesh format.
-}
-- TODO: IndexMap sharedBlendIndexToBoneIndexMap;
    }

{-
-- TODO: create generic functions which operate on buffer elements
mapFloatType3M_ :: (FloatType -> FloatType -> FloatType -> IO a) -> (Int,Ptr FloatType,Int) -> IO ()
mapFloatType3M_ f (cnt,ptr,stride) = do
    let s' = if stride == 0 then 4 else stride
    mapM_ (g ptr s') [0..(cnt-1)]
  where
    g ptr stride i = do
        let p = plusPtr ptr $ stride * i
        x <- peekElemOff p 0
        y <- peekElemOff p 1
        z <- peekElemOff p 2
        f x y z

foldFloatType3M :: ((FloatType,FloatType,FloatType) -> b -> b) -> b -> (Int,Ptr FloatType,Int) -> IO b
foldFloatType3M f a (cnt,ptr,stride) = do
    let s' = if stride == 0 then 4 else stride
    foldM (g ptr s') a [0..(cnt-1)]
  where
    g ptr stride e i = do
        let p = plusPtr ptr $ stride * i
        x <- peekElemOff p 0
        y <- peekElemOff p 1
        z <- peekElemOff p 2
        return $ f (x,y,z) e
-}

--calculateBoundingRadius :: Mesh -> IO FloatType
--calculateBoundingRadius m = do
    -- collect vertex data
    -- find 
--    return