-- This source file is part of HGamer3D -- (A project to enable 3D game development in Haskell) -- For the latest info, see http://www.althainz.de/HGamer3D.html -- -- (c) 2011 Peter Althainz -- -- Licensed under the Apache License, Version 2.0 (the "License"); -- you may not use this file except in compliance with the License. -- You may obtain a copy of the License at -- -- http://www.apache.org/licenses/LICENSE-2.0 -- -- Unless required by applicable law or agreed to in writing, software -- distributed under the License is distributed on an "AS IS" BASIS, -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- See the License for the specific language governing permissions and -- limitations under the License. -- Object3D.hs -- -- Graphics Objects 3D functionality module HGamer3D.APIs.Base.Graphics3D.Object3D ( Object3D (..), Material (..), createSphere, createCube, createPlane, createMesh, createLine, setObjectMaterial, combineObjects ) where import GHC.Ptr import HGamer3D.Bindings.Ogre.ClassPtr import HGamer3D.Bindings.Ogre.Utils import HGamer3D.Data.Colour import HGamer3D.Data.Vector import HGamer3D.Data.Angle import HGamer3D.Bindings.Ogre.StructColour import HGamer3D.Bindings.Ogre.StructSharedPtr import HGamer3D.Bindings.Ogre.EnumSceneType import HGamer3D.Bindings.Ogre.EnumNodeTransformSpace import HGamer3D.Bindings.Ogre.EnumLightType import HGamer3D.Bindings.Ogre.ClassCamera as Camera import HGamer3D.Bindings.Ogre.ClassRoot as Root import HGamer3D.Bindings.Ogre.ClassLight as Light import HGamer3D.Bindings.Ogre.ClassNode as Node import HGamer3D.Bindings.Ogre.ClassSceneManager as SceneManager import HGamer3D.Bindings.Ogre.ClassSceneNode as SceneNode import HGamer3D.Bindings.Ogre.ClassRenderTarget as RenderTarget import HGamer3D.Bindings.Ogre.ClassRenderWindow as RenderWindow import HGamer3D.Bindings.Ogre.ClassResourceGroupManager as ResourceGroupManager import HGamer3D.Bindings.Ogre.ClassTextureManager as TextureManager import HGamer3D.Bindings.Ogre.ClassControllerManager as ControllerManager import HGamer3D.Bindings.Ogre.ClassViewport as Viewport import HGamer3D.Bindings.Ogre.ClassFrustum as Frustum import HGamer3D.Bindings.Ogre.ClassAnimationState as AnimationState import HGamer3D.Bindings.Ogre.ClassEntity as Entity import HGamer3D.Bindings.Ogre.ClassControllerManager as ControllerManager import HGamer3D.Bindings.Ogre.ClassWindowEventUtilities as WindowEventUtilities import HGamer3D.Bindings.Ogre.ClassManualObject as ManualObject import HGamer3D.Bindings.Ogre.EnumRenderOperationOperationType import HGamer3D.Bindings.Ogre.StructHG3DClass import HGamer3D.Bindings.Ogre.EnumSceneManagerPrefabType import HGamer3D.Data.HG3DClass import Control.Monad.Trans import Control.Monad.Reader import Control.Monad.State import HGamer3D.APIs.Base.Common import HGamer3D.APIs.Base.Graphics3D.Engine3D data Object3D = Object3D HG3DClass HG3DClass | -- node entity Object3DCombined HG3DClass -- node only getNode :: Object3D -> HG3DClass getNode (Object3D node entity) = node getNode (Object3DCombined node) = node data Material = NamedMaterial String createObjectFromEntity :: HG3DClass -> EngineSystem -> IO Object3D createObjectFromEntity entity es = do rootNode <- SceneManager.getRootSceneNode (esSceneManager es) let vzero = Vec3 0.0 0.0 0.0 let qident = Q (Vec4 1.0 0.0 0.0 0.0) node <- SceneNode.createChildSceneNode rootNode vzero qident SceneNode.attachObject node entity return (Object3D node entity) createSphere :: MHGamer3D Object3D createSphere = do (cs, es) <- ask entity <- liftIO $ SceneManager.createEntity4 (esSceneManager es) PT_SPHERE ob <- liftIO $ createObjectFromEntity entity es return (ob) createCube :: MHGamer3D Object3D createCube = do (cs, es) <- ask entity <- liftIO $ SceneManager.createEntity4 (esSceneManager es) PT_CUBE ob <- liftIO $ createObjectFromEntity entity es return (ob) createPlane :: MHGamer3D Object3D createPlane = do (cs, es) <- ask entity <- liftIO $ SceneManager.createEntity4 (esSceneManager es) PT_PLANE ob <- liftIO $ createObjectFromEntity entity es return (ob) createMesh :: String -> MHGamer3D Object3D createMesh name = do (cs, es) <- ask entity <- liftIO $ SceneManager.createEntity2 (esSceneManager es) name ob <- liftIO $ createObjectFromEntity entity es return (ob) createLine :: Vec3 -> Vec3 -> MHGamer3D Object3D createLine vStart vEnd = do (cs, es) <- ask lineName <- lift $ getUniqueName "GO" name <- lift $ getUniqueName "GO" let materialName = "BaseWhiteNoLighting" let colour = Colour 1.0 1.0 1.0 1.0 mo <- liftIO $ SceneManager.createManualObject (esSceneManager es) lineName liftIO $ ManualObject.begin mo materialName OT_LINE_LIST "General" liftIO $ ManualObject.position mo vStart liftIO $ ManualObject.colour mo colour liftIO $ ManualObject.position mo vEnd liftIO $ ManualObject.colour mo colour liftIO $ ManualObject.end mo mesh <- liftIO $ ManualObject.convertToMesh mo name "General" obj <- createMesh name return (obj) instance Position3D Object3D where position3D obj = do pos <- liftIO $ Node.getPosition (getNode obj) return (pos) positionTo3D obj pos = do liftIO $ Node.setPosition (getNode obj) pos return () instance Scale3D Object3D where scale3D obj = do pos <- liftIO $ Node.getScale (getNode obj) return (pos) scaleTo3D obj pos = do liftIO $ Node.setScale (getNode obj) pos return () instance Orientation3D Object3D where orientation3D obj = do q <- liftIO $ Node.getOrientation (getNode obj) let uq = mkNormal q return uq orientationTo3D obj uq = do liftIO $ Node.setOrientation (getNode obj) (fromNormal uq) return () setObjectMaterial :: Object3D -> Material -> MHGamer3D () setObjectMaterial (Object3D node entity) (NamedMaterial name) = do liftIO $ Entity.setMaterialName entity name "General" setObjectMaterial (Object3DCombined node) (NamedMaterial name) = do liftIO $ print "try to set material of combined object, not possible" -- |This function groups objects into a new object -- it is not perfoming any geometric operations, it just groups the -- input objects. Can be used, to move and rotate a group. combineObjects :: [Object3D] -- ^A list of objects, to be grouped -> MHGamer3D (Object3D) -- ^The return value is a new GraphicsObject combineObjects listObjects = do (cs, es) <- ask rootNode <- liftIO $ SceneManager.getRootSceneNode (esSceneManager es) let vzero = Vec3 0.0 0.0 0.0 let qident = Q (Vec4 1.0 0.0 0.0 0.0) node <- liftIO $ SceneNode.createChildSceneNode rootNode vzero qident sequence_ (map ( \(Object3D objectnode object) -> do parent <- liftIO $ Node.getParent objectnode -- currently no check here, if parent exists! -- no parent is only valid for root node and this is not accessible to the -- user of this api (should not be used, at least) liftIO $ Node.removeChild2 parent objectnode liftIO $ Node.addChild node objectnode return () ) listObjects) return ( Object3DCombined node )