[HOpenGL] Scene Graph manual transformation problem
Ben Christy
ben.christy at gmail.com
Thu Nov 11 08:27:46 EST 2010
I have a problem with implementing the transformations for my scene graph
manually. After removing the opengl functions translate and rotate form my
program and managing the matrix by hand my scene is no longer
transformed correctly and I am at a loss. My guess is that it has something
to do with the order I am doing something as my scene appears to be rotated
and then translated. As I walk down the scene graph I multiply the current
matrix by a series of translation matrices
SceneGraph =
buildSSG =
SimpleRootNode "HomeWork3"
[
TransformNode "camera" (Rotate 0 0 0) (Translate 0 0 (-1))
[
TransformNode "ground" (Rotate 0 0 0) (Translate (-4) (-1.5)
(-4))
[
ModelNode "groundModel" (Just groundModel)
],
TransformNode "carousel" (Rotate 0 0 0) (Translate 0 0 0)
[
TransformNode "carouselbase" (Rotate 90 0 0) (Translate 0 0
0)
[
ModelNode "carouselbaseModel" (Just carouselBase)
],
TransformNode "carouselRoof" (Rotate 90 0 0) (Translate 0
0.3 0)
[
ModelNode "carouselRoofModel" (Just carouselRoof)
],
TransformNode "carouselFloor" (Rotate 90 0 0) (Translate 0 0
0)
[
ModelNode "carouselFloorModel" (Just carouselFloor),
TransformNode "polls" (Rotate 0 0 0) (Translate 0 0
(-0.2))
[
OrbitalTransformNode "poll1"(Rotate 0 0 0 )
(Translate 0 0.45 0)
[
ModelNode "poll1Model" (Just carouselPool),
TransformNode "horse1" (Rotate 0 0 0 )
(Translate 0 0 0)
[
ModelNode "horse1Model" (Just horseModel)
]
],
OrbitalTransformNode "poll2" (Rotate 0 0 45)
(Translate 0 0.45 0)
[
ModelNode "poll2Model" (Just carouselPool),
TransformNode "horse2" (Rotate 0 0 0)
(Translate 0 0 0)
[
ModelNode "horse2Model" (Just horseModel)
]
],
OrbitalTransformNode "poll3" (Rotate 0 0 90)
(Translate 0 0.45 0)
[
ModelNode "poll3Model" (Just carouselPool),
TransformNode "horse3" (Rotate 0 0 0)
(Translate 0 0 0)
[
ModelNode "horse3Model" (Just horseModel)
]
],
OrbitalTransformNode "poll4" (Rotate 0 0 135)
(Translate 0 0.45 0)
[
ModelNode "poll4Model" (Just carouselPool),
TransformNode "horse4" (Rotate 0 0 0)
(Translate 0 0 0)
[
ModelNode "horse4Model" (Just horseModel)
]
],
OrbitalTransformNode "poll5" (Rotate 0 0 180)
(Translate 0 0.45 0)
[
ModelNode "poll5Model" (Just carouselPool),
TransformNode "horse5" (Rotate 0 0 0)
(Translate 0 0 0)
[
ModelNode "horse5Model" (Just horseModel)
]
],
OrbitalTransformNode "poll6" (Rotate 0 0 225)
(Translate 0 0.45 0)
[
ModelNode "poll6Model" (Just carouselPool),
TransformNode "horse6" (Rotate 0 0 0)
(Translate 0 0 0)
[
ModelNode "horse6Model" (Just horseModel)
]
],
OrbitalTransformNode "poll7" (Rotate 0 0 270)
(Translate 0 0.45 0)
[
ModelNode "poll7Model" (Just carouselPool),
TransformNode "horse7" (Rotate 0 0 0) (Translate
0 0 0)
[
ModelNode "horse7Model" (Just horseModel)
]
],
OrbitalTransformNode "poll8" (Rotate 0 0 315)
(Translate 0 0.45 0)
[
ModelNode "poll8Model" (Just carouselPool),
TransformNode "horse8" (Rotate 0 0 0) (Translate
0 0 0)
[
ModelNode "horse8Model" (Just horseModel)
]
]
]
],
TransformNode "carouselCeiling" (Rotate 90 0 0) (Translate 0
0.2 0)
[
ModelNode "carouselCeilingModel" (Just carouselFloor)
]
]
]
]
where
groundModel = ClassicModel(0,0,0) (heightMapToVerts(genHeightMap 6 1
1.6 1.2 1.7) 0.1 0 3)
carouselBase = GluShape (50,50,50) 0.55 0.550 0.55 0.550 0.550 0.550
1(Cylinder 0.5 0.5 0.05 20 20) (QuadricStyle(Just Smooth)
NoTextureCoordinates Outside FillStyle)
carouselRoof = GluShape (50,50,50) 0.55 0.55 0.55 0.550 0.550 0.550
1(Cylinder 0.001 0.5 0.1 20 20) (QuadricStyle(Just Smooth)
NoTextureCoordinates Outside FillStyle)
carouselPool = GluShape (50,50,50) 0.55 0.55 0.55 0.550 0.550 0.550
1(Cylinder 0.005 0.005 0.2 20 20) (QuadricStyle(Just Smooth)
NoTextureCoordinates Outside FillStyle)
carouselFloor = GluShape (50,50,50) 0.55 0.55 0.55 0.550 0.550 0.550
1(Disk 0 0.5 20 20) (QuadricStyle(Just Smooth)
NoTextureCoordinates Outside FillStyle)
horseModel = GluShape (50,50,50) 0.55 0.55 0.55 0.550 0.550 0.550
1(Sphere 0.03 20 20) (QuadricStyle(Just Smooth)
NoTextureCoordinates Outside FillStyle)
SceneGraph module=
module SimpleSceneGraph (
findNodeByID,
updateSceneGraph,
GraphChange(DeleteNode, AddNode, RotateNode, TranslateNode),
Model(ClassicModel, ModernModel, GluShape),
Translate(Translate),
Rotate(Rotate),
CameraPos(CameraPos),
LookAt(LookAt),
UpVector(UpVector),
Vert(Vert),
vertexTupleListToVertexList,
initModelVBO,
getChanges,
identityMatrix,
DrawSceneGraph,
SimpleSceneGraph(SimpleRootNode,SimpleCameraNode, SimpleLightNode,
ModelNode, TransformNode, OrbitalTransformNode),
render,
getColorAtPixel,
pngToArray
)
where
import Graphics.Rendering.OpenGL
import Data.IORef
import Graphics.UI.GLUT
import Foreign.Storable
import Control.Monad.ST.Strict
import Data.Array.MArray
import Data.Array.Storable
import Foreign.Ptr
import qualified Data.Map as Map
import qualified Data.HashTable as Hashtable
import Graphics.Rendering.OpenGL.Raw.ARB.Compatibility
import Graphics.Rendering.GLU.Raw
import Graphics.Rendering.OpenGL.GLU
import Data.Int
import Prelude
import Codec.Image.PNG
data OpenGLType = ClassicGL
| ModernGL
openGLType = ModernGL
class DrawSceneGraph a where
process:: a→ IO Bool
data Translate = Translate {
tx::GLfloat,
ty::GLfloat,
tz::GLfloat
}
data Rotate = Rotate{
angleX::GLfloat,
angleY::GLfloat,
angleZ::GLfloat}
data CameraPos = CameraPos { cpx::GLdouble,
cpy::GLdouble,
cpz::GLdouble}
data LookAt = LookAt { lx::GLdouble,
ly::GLdouble,
lz::GLdouble}
data UpVector = UpVector { uvx::GLdouble,
uvy::GLdouble,
uvz::GLdouble}
data SimpleSceneGraph = SimpleRootNode { nid::String,
children::[SimpleSceneGraph]}
|TransformNode {
nid::String,
rotation::Rotate,
translation::Translate,
children::[SimpleSceneGraph]}
|OrbitalTransformNode
{
nid::String,
rotation::Rotate,
translation::Translate,
children::[SimpleSceneGraph]
}
| ModelNode {
nid::String,
model::(Maybe Model)
}
-- | SimpleNode {
-- nid::String,
-- model::(Maybe Model),
-- rotation::Rotate,
-- translation::Translate,
-- children::[SimpleSceneGraph]}
| SimpleLightNode {
nid::String,
rotation::Rotate,
translation::Translate,
amb::Color4 GLfloat,
diff::Color4 GLfloat,
spec::Color4 GLfloat,
children::[SimpleSceneGraph]}
-- | OrbitalNode {
-- nid::String,
-- model::(Maybe Model),
-- rotation::Rotate,
-- translation::Translate,
-- children::[SimpleSceneGraph]}
| SimpleCameraNode {
nid::String,
cameraPos::CameraPos,
lookAT:: LookAt,
upVector::UpVector,
children::[SimpleSceneGraph]}
class RenderSimpleSceneGraph a where
render :: Matrix4x4 → a → IO ()
data Matrix4x4 = Matrix4x4 {
i1j1 ::GLfloat,
i1j2 ::GLfloat,
i1j3 ::GLfloat,
i1j4 ::GLfloat,
i2j1 ::GLfloat,
i2j2 ::GLfloat,
i2j3 ::GLfloat,
i2j4 ::GLfloat,
i3j1 ::GLfloat,
i3j2 ::GLfloat,
i3j3 ::GLfloat,
i3j4 ::GLfloat,
i4j1 ::GLfloat,
i4j2 ::GLfloat,
i4j3 ::GLfloat,
i4j4 ::GLfloat
} deriving (Show)
identityMatrix =
Matrix4x4 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1
rotateX θ =
if θ ≠ 0
then Matrix4x4 1 0 0 0 0 (cos rad) (-(sin rad)) 0 0 (sin rad) (cos
rad) 0 0 0 0 1
else identityMatrix
where
rad = θ * pi / 180
rotateY θ =
if θ ≠ 0
then Matrix4x4 (cos rad) 0 (sin rad) 0 0 1 0 0 (-(sin rad)) 0 (cos
rad) 0 0 0 0 1
else identityMatrix
where
rad = θ * pi / 180
rotateZ θ =
if θ ≠ 0
then Matrix4x4 (cos rad) (-(sin rad)) 0 0 (sin rad) (cos rad) 0 0 0
0 1 0 0 0 0 1
else identityMatrix
where
rad = θ * pi / 180
trans (Vector3 x y z) =
Matrix4x4 1 0 0 x 0 1 0 y 0 0 1 z 0 0 0 1
mult:: Matrix4x4 → Matrix4x4 → Matrix4x4
mult mL mR =
Matrix4x4 x1y1 x1y2 x1y3 x1y4 x2y1 x2y2 x2y3 x2y4 x3y1 x3y2 x3y3 x3y4
x4y1 x4y2 x4y3 x4y4
where
x1y1 = (i1j1 mL) * (i1j1 mR) + (i1j2 mL) * (i2j1 mR) + (i1j3 mL) *
(i3j1 mR) + (i1j4 mL) * (i4j1 mR)
x1y2 = (i1j1 mL) * (i1j2 mR) + (i1j2 mL) * (i2j2 mR) + (i1j3 mL) *
(i3j2 mR) + (i1j4 mL) * (i4j2 mR)
x1y3 = (i1j1 mL) * (i1j3 mR) + (i1j2 mL) * (i2j3 mR) + (i1j3 mL) *
(i3j3 mR) + (i1j4 mL) * (i4j3 mR)
x1y4 = (i1j1 mL) * (i1j4 mR) + (i1j2 mL) * (i2j4 mR) + (i1j3 mL) *
(i3j4 mR) + (i1j4 mL) * (i4j4 mR)
x2y1 = (i2j1 mL) * (i1j1 mR) + (i2j2 mL) * (i2j1 mR) + (i2j3 mL) *
(i3j1 mR) + (i2j4 mL) * (i4j1 mR)
x2y2 = (i2j1 mL) * (i1j2 mR) + (i2j2 mL) * (i2j2 mR) + (i2j3 mL) *
(i3j2 mR) + (i2j4 mL) * (i4j2 mR)
x2y3 = (i2j1 mL) * (i1j3 mR) + (i2j2 mL) * (i2j3 mR) + (i2j3 mL) *
(i3j3 mR) + (i2j4 mL) * (i4j3 mR)
x2y4 = (i2j1 mL) * (i1j4 mR) + (i2j2 mL) * (i2j4 mR) + (i2j3 mL) *
(i3j4 mR) + (i2j4 mL) * (i4j4 mR)
x3y1 = (i3j1 mL) * (i1j1 mR) + (i3j2 mL) * (i2j1 mR) + (i3j3 mL) *
(i3j1 mR) + (i3j4 mL) * (i4j1 mR)
x3y2 = (i3j1 mL) * (i1j2 mR) + (i3j2 mL) * (i2j2 mR) + (i3j3 mL) *
(i3j2 mR) + (i3j4 mL) * (i4j2 mR)
x3y3 = (i3j1 mL) * (i1j3 mR) + (i3j2 mL) * (i2j3 mR) + (i3j3 mL) *
(i3j3 mR) + (i3j4 mL) * (i4j3 mR)
x3y4 = (i3j1 mL) * (i1j4 mR) + (i3j2 mL) * (i2j4 mR) + (i3j3 mL) *
(i3j4 mR) + (i3j4 mL) * (i4j4 mR)
x4y1 = (i4j1 mL) * (i1j1 mR) + (i4j2 mL) * (i2j1 mR) + (i4j3 mL) *
(i3j1 mR) + (i4j4 mL) * (i4j1 mR)
x4y2 = (i4j1 mL) * (i1j2 mR) + (i4j2 mL) * (i2j2 mR) + (i4j3 mL) *
(i3j2 mR) + (i4j4 mL) * (i4j2 mR)
x4y3 = (i4j1 mL) * (i1j3 mR) + (i4j2 mL) * (i2j3 mR) + (i4j3 mL) *
(i3j3 mR) + (i4j4 mL) * (i4j3 mR)
x4y4 = (i4j1 mL) * (i1j4 mR) + (i4j2 mL) * (i2j4 mR) + (i4j3 mL) *
(i3j4 mR) + (i4j4 mL) * (i4j4 mR)
matrix4x4toList (Matrix4x4 i1j1 i1j2 i1j3 i1j4 i2j1 i2j2 i2j3 i2j4
i3j1 i3j2 i3j3 i3j4 i4j1 i4j2 i4j3 i4j4)
= [i1j1,
i1j2,i1j3,i1j4,i2j1,i2j2,i2j3,i2j4,i3j1,i3j2,i3j3,i3j4,i4j1,i4j2,i4j3,i4j4]
matrix4x4toGLMatrix (Matrix4x4 i1j1 i1j2 i1j3 i1j4 i2j1 i2j2 i2j3 i2j4
i3j1 i3j2 i3j3 i3j4 i4j1 i4j2 i4j3 i4j4)=
newMatrix RowMajor matList :: IO (GLmatrix GLfloat)
where
matList = [i1j1,
i1j2,i1j3,i1j4,i2j1,i2j2,i2j3,i2j4,i3j1,i3j2,i3j3,i3j4,i4j1,i4j2,i4j3,i4j4]
classicTransform matrix = do
matrixMode $= Modelview 0
loadIdentity
print "classic matrix operation"
m ← newMatrix RowMajor (matrix4x4toList matrix) :: IO (GLmatrix
GLfloat)
multMatrix m
return ()
data GraphChange = DeleteNode {
cid ::String}
| RotateNode {
cid ::String,
cx ::GLfloat,
cy ::GLfloat,
cz ::GLfloat}
| TranslateNode {
cid ::String,
cx ::GLfloat,
cy ::GLfloat,
cz ::GLfloat}
| AddNode {
parentid::String,
newNode::SimpleSceneGraph}
data Vert = Vert {
vertX::GLfloat,
vertY::GLfloat,
vertZ::GLfloat,
colorR::GLfloat,
colorG::GLfloat,
colorB::GLfloat,
specR::GLfloat,
specG::GLfloat,
specB::GLfloat,
shiny::GLfloat}
deriving (Show)
data Model = ClassicModel{
colorID::(GLubyte,GLubyte,GLubyte),
verts::[Vert]}
| GluShape{
colorID::(GLubyte,GLubyte,GLubyte),
shapeR::GLfloat,
shapeG::GLfloat,
shapeB::GLfloat,
shapeSpecR::GLfloat,
shapeSpecG::GLfloat,
shapeSpecB::GLfloat,
shapeShiny::GLfloat,
shape ::(QuadricPrimitive),
style :: QuadricStyle}
| ModernModel{
vboData:: IO BufferObject,
vertCount:: Int
}
instance RenderSimpleSceneGraph Model where
render matrix (ClassicModel (r,g,b) verts ) = do
print "a model"
classicTransform matrix
--color $ Color3 r g b
renderPrimitive Triangles $ mapM_ renderVert verts
render matrix (GluShape (r, g ,b) r1 g1 b1 sR sG sB shiny shape style) =
do
color $ Color3 r1 g1 b1
materialAmbientAndDiffuse FrontAndBack $= (Color4 r1 g1 b1 1)
materialSpecular FrontAndBack $= (Color4 sR sG sB 1)
materialShininess FrontAndBack $= shiny
renderQuadric style shape
renderVert (Vert x y z r g b sR sG sB shiny) = do
color $ Color3 r g b
materialAmbientAndDiffuse FrontAndBack $= (Color4 r g b 1)
materialSpecular FrontAndBack $= (Color4 sR sG sB 1)
materialShininess FrontAndBack $= shiny
vertex $ Vertex3 x y z
instance RenderSimpleSceneGraph SimpleSceneGraph where
render matrix (SimpleRootNode id children) = do
--matrixMode $= Projection
--loadIdentity
--depthFunc $= Just Less
--viewport $= (Position 0 0, Size 800 600)
--perspective 60 1.333 1 120
clear [ColorBuffer, DepthBuffer]
lighting $= Enabled
light (Light 0) $= Enabled
matrixMode $= Modelview 0
loadIdentity
traverseChildren matrix children
flush
swapBuffers
return ()
render matrix (ModelNode id model) = do
--print $ "drawing" ⊕ id
--show matrix
case model of
Nothing → return()
Just model1 → render matrix model1
render matrix (OrbitalTransformNode id (Rotate aX aY aZ) (Translate x y
z) children) = do
print $ "drawing" ⊕ id
print translatedMat
traverseChildren translatedMat children
return ()
where
rotatedXMat = (rotateX aX) `mult` matrix
rotatedYMat = (rotateY aY) `mult`rotatedXMat
rotatedZMat = (rotateZ aZ) `mult`rotatedYMat
translatedMat = (trans (Vector3 x y z)) `mult` rotatedZMat
render matrix (TransformNode id (Rotate aX aY aZ) (Translate x y z)
children) = do
print $ "drawing" ⊕ id
print rotatedZMat
traverseChildren rotatedZMat children
return ()
where
translatedMat = (trans (Vector3 x y z)) `mult` matrix
rotatedXMat = (rotateX aX) `mult` translatedMat
rotatedYMat = (rotateY aY) `mult` rotatedXMat
rotatedZMat = (rotateZ aZ) `mult` rotatedYMat
render matrix (SimpleLightNode nid rotation translation amb diff spec
children) = do
ambient (Light 0) $= amb
diffuse (Light 0) $= diff
specular (Light 0) $= spec
position (Light 0) $= (Vertex4 1 1 1 0)
where
transX = tx translation
transY = ty translation
transZ = tz translation
--angleRot = rangle rotation
--rotX = rx rotation
--rotY = ry rotation
--rotZ = rz rotation
translateRotateDraw = do
--translate (Vector3 transX transY transZ)
--rotate angleRot (Vector3 rotX rotY rotZ)
traverseChildren matrix children
--render matrix (SimpleNode id model rotation translation children) = do
-- print $ "drawing" ⊕ id
-- preservingMatrix translateRotateDraw
-- return ()
-- where
-- transX = tx translation
-- transY = ty translation
-- transZ = tz translation
-- angleRot = rangle rotation
-- rotX = rx rotation
-- rotY = ry rotation
-- rotZ = rz rotation
-- translateRotateDraw = do
--
-- translate (Vector3 transX transY transZ)
-- rotate angleRot (Vector3 rotX rotY rotZ)
-- traverseChildren matrix children
-- case model of
-- Nothing → return ()
-- Just m1 → render matrix m1
--render matrix (OrbitalNode id model rotation translation children) =
do
-- print $ "drawing" ⊕ id
-- preservingMatrix translateRotateDraw
-- return ()
-- where
-- transX = tx translation
-- transY = ty translation
-- transZ = tz translation
-- angleRot = rangle rotation
-- rotX = rx rotation
-- rotY = ry rotation
-- rotZ = rz rotation
-- translateRotateDraw = do
-- rotate angleRot (Vector3 rotX rotY rotZ)
-- translate (Vector3 transX transY transZ)
-- traverseChildren matrix children
-- case model of
-- Nothing → return ()
-- Just m1 → render matrix m1
render matrix (SimpleCameraNode id (CameraPos posX posY posZ) (LookAt
lookX lookY lookZ)
(UpVector upX upY upZ) children) = do
print $ "drawing" ⊕ id
gluLookAt posX posY posZ lookX lookY lookZ upX upY upZ
traverseChildren matrix children
return ()
traverseChildren:: Matrix4x4 → [SimpleSceneGraph]→ IO ()
traverseChildren matrix (x:xs) = do
render matrix x
traverseChildren matrix xs
traverseChildren _ [] = do
return ()
initModelVBO :: [GLfloat] → IO BufferObject
initModelVBO vertexList = do
[models]← genObjectNames 1 :: IO [BufferObject]
bindBuffer ArrayBuffer $= Just models
tempArray ← newListArray (0, listLen - 1) vertexList :: IO(StorableArray
Int GLfloat)
withStorableArray tempArray (λptr ->
bufferData ArrayBuffer $= (sizeOfList, ptr, StaticDraw))
bindBuffer ArrayBuffer $= Nothing
return models
where
listLen = length vertexList
elementSize = sizeOf $ head vertexList
sizeOfList = toEnum $ listLen * elementSize
vertexTupleListToVertexList::[(GLfloat,GLfloat,GLfloat)]→ [GLfloat]
vertexTupleListToVertexList [] = []
vertexTupleListToVertexList ((x,y,z):verts) =
x:y:z:vertexTupleListToVertexList verts
--Takes a list of changes, should be hashtable though, and a SceneGraph
--It then recursivly rebuild the graph making any change in the changes
--data structure
updateSceneGraph :: Map.Map String [GraphChange]→ SimpleSceneGraph →
SimpleSceneGraph
-- A root node can ¬ be changed or deleted and can only apear once as the
ROOT
--failing to follow these rules will result in undefined behaviors
updateSceneGraph changes (SimpleRootNode id children) =
SimpleRootNode id (updateChildren children changes)
updateSceneGraph changes graph =
graph
findNodeByID id graph =
if graphID ≡ id
then Just graph
else findNodeByIDChildren Nothing id (children graph)
where
graphID = nid graph
findNodeByIDChildren (Just graph) _ _ = Just graph
findNodeByIDChildren accum id (c:cs) =
findNodeByIDChildren (findNodeByID id c) id cs
findNodeByIDChildren accum _ [] = accum
updateChildren :: [SimpleSceneGraph] → Map.Map String [GraphChange] →
[SimpleSceneGraph]
updateChildren [] changes = []
updateChildren (n:ns) changes =
case newN of
Nothing → (updateChildren ns changes)
Just node → node:(updateChildren ns changes)
where
nodeID = nid n
newN = applyAllChanges (Just n) applicableChanges changes
applicableChanges = getChanges nodeID changes
--Takes a String node id and returns all changes that apply to it
getChanges::String→ Map.Map String [GraphChange]→ [GraphChange]
getChanges id map =
case changes of
Nothing → []
Just cs → cs
where
changes = Map.lookup id map
--Applies all changes for a node to that node
applyAllChanges::(Maybe SimpleSceneGraph) → [GraphChange] → Map.Map String
[GraphChange] → (Maybe SimpleSceneGraph)
applyAllChanges Nothing _ _ =
Nothing
applyAllChanges (Just node) (c:cs) allChanges =
applyAllChanges (updateNode node c ) cs allChanges
applyAllChanges (Just (TransformNode id rotation trans children)) []
allChanges =
Just (TransformNode id rotation trans (updateChildren children
allChanges))
applyAllChanges (Just (OrbitalTransformNode id rotation trans children)) []
allChanges =
Just (OrbitalTransformNode id rotation trans (updateChildren children
allChanges))
applyAllChanges (Just (ModelNode id model)) [] allChanges =
Just (ModelNode id model)
applyAllChanges (Just (SimpleCameraNode id pos look up children)) []
allChanges =
Just (SimpleCameraNode id pos look up (updateChildren children
allChanges))
applyAllChanges ( Just(SimpleLightNode id rot trans amb diff spec children))
[] allChanges =
Just (SimpleLightNode id rot trans amb diff spec (updateChildren
children allChanges))
--Updates a single node with a single Change
--Returns Just Node or Nothing if a delete change was requested
updateNode:: SimpleSceneGraph→ GraphChange→ (Maybe SimpleSceneGraph)
updateNode (SimpleCameraNode id pos lookat up children) (TranslateNode tId x
y z)=
Just (SimpleCameraNode id (CameraPos (realToFrac x) (realToFrac y)
(realToFrac z)) lookat up children)
updateNode (TransformNode id rotation translation children) (TranslateNode
tId x y z)=
Just (TransformNode id rotation (Translate x y z) children)
updateNode (TransformNode id rotation translation children) (RotateNode tId
x y z)=
Just (TransformNode id (Rotate x y z) translation children)
updateNode (TransformNode id rotation translation children) _=
Just (TransformNode id rotation translation children)
--updateNode (OrbitalNode id model rotation translation children)
(TranslateNode tId x y z)=
-- Just (OrbitalNode id model rotation (Translate x y z) children)
--updateNode (OrbitalNode id model rotation translation children)
(RotateNode tId r x y z)=
--Just (OrbitalNode id model (Rotate r x y z) translation children)
updateNode (OrbitalTransformNode id rotation translation children) _=
Just (OrbitalTransformNode id rotation translation children)
updateNode (ModelNode id model) _ =
Just(ModelNode id model)
updateNode _ (DeleteNode id) = Nothing
pngToArray (Right png) = do
Just (imageData png)
pngToArray (Left error) = do
Nothing
getColorAtPixel x y = do
colorArray ← newArray (0, 2) 0 :: IO(StorableArray Int Int)
vp ← get viewport
adjustedY ← return $ adjustY vp
withStorableArray colorArray (λptr ->
readPixels (Position x (fromIntegral adjustedY)) (Size 1 1 )
(PixelData RGB UnsignedByte ptr))
touchStorableArray colorArray
colors ← getElems colorArray
return $ head colors
where
adjustY vp = (extractSizeY vp) - y
extractSizeY (_, (Size x y)) = fromIntegral y :: GLint
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/hopengl/attachments/20101111/a0b85663/attachment-0001.html
More information about the HOpenGL
mailing list