-----------------------------------------------------------------------
-- An example of Actor Prolog program.                               --
-- (c) 2012 IRE RAS Alexei A. Morozov                                --
-----------------------------------------------------------------------

import .. from "morozov/Java3D";

class 'Main' (specialized 'Canvas3D'):
--
bounds          : BoundingSphere
                        = 'BoundingSphere'({});
--
wireframe       : Appearance
                        = 'Appearance'({
                                polygonAttributes: 'PolygonAttributes'({
                                        rasterizationMode: 'POLYGON_LINE',
                                        cullFace: 'CULL_BACK',
                                        polygonOffsetBias: 0
                                        }),
                                coloringAttributes: 'ColoringAttributes'({
                                        color: color3(0,0,0),
                                        shadeModel: 'SHADE_FLAT'
                                        })
                                });
solid           : Appearance
                        = 'Appearance'({
                                material: 'Material'({})
                                });
glass           : Appearance
                        = 'Appearance'({
                                material: 'Material'({}),
                                transparencyAttributes: 'TransparencyAttributes'({
                                        transparency: 0.5,
                                        transparencyMode: 'NICEST'
                                        })
                                });
--
background_color                = 'White';
enable_scene_antialiasing       = 'yes';
--
width                           = 40;
--
internal:
--
con                     = ('Console',
                                x= 40,
                                width= 40);
--
[
PREDICATES:
--
imperative:
--
create_tetrahedron = Shape3D;
--
create_dodecahedron = Shape3D;
dodecahedron_vertices(Vertices)                 - (o);
dodecahedron_phi(Numerical)                     - (o);
--
update_appearance(NodeLabels,Appearance)        - (i,i);
--
'/'(Numerical,Numerical) = Numerical            - (i,i);
'-'(Numerical) = Numerical                      - (i);
--
CLAUSES:
--
goal:-!,
        SimpleNodes== [
                'Sphere'({
                        label: "MySphere1",
                        radius: 0.7,
                        divisions: 100,
                        enableGeometryPicking: 'yes',
                        enableAppearanceModify: 'yes',
                        generateNormals: 'yes',
                        appearance: wireframe
                        }),
                'Box'({
                        label: "MyBox",
                        xdim: 1.2,
                        ydim: 0.3,
                        zdim: 0.8,
                        enableGeometryPicking: 'yes',
                        enableAppearanceModify: 'yes',
                        generateNormals: 'yes',
                        appearance: wireframe
                        }),
                'TransformGroup'({
                        transform3D: 'Transform3D'({
                                translation: [0,1.5,0]
                                }),
                        branches: [
                                'Sphere'({
                                        label: "MySphere2",
                                        radius: 1.0,
                                        divisions: 100,
                                        enableGeometryPicking: 'yes',
                                        enableAppearanceModify: 'yes',
                                        generateNormals: 'yes',
                                        appearance: wireframe
                                        })
                                ]
                        }),
                'TransformGroup'({
                        transform3D: 'Transform3D'({
                                translation: [-1,-1.5,0]
                                        }),
                        branches: [
                                'Cylinder'({
                                        label: "MyCylinder",
                                        radius: 1.0,
                                        height: 2.0,
                                        xdivisions: 100,
                                        ydivisions: 1,
                                        enableGeometryPicking: 'yes',
                                        enableAppearanceModify: 'yes',
                                        generateNormals: 'yes',
                                        appearance: wireframe
                                        })
                                ]
                        }),
                'TransformGroup'({
                        transform3D: 'Transform3D'({
                                translation: [1,-1.5,0]
                                }),
                        branches: [
                                'Cone'({
                                        label: "MyCone",
                                        radius: 1.0,
                                        height: 2.0,
                                        xdivisions: 100,
                                        ydivisions: 1,
                                        enableGeometryPicking: 'yes',
                                        enableAppearanceModify: 'yes',
                                        generateNormals: 'yes',
                                        appearance: wireframe
                                        })
                                ]
                        })
                ],
        Tetrahedron== ?create_tetrahedron(),
        Dodecahedron== ?create_dodecahedron(),
        show([
                'TransformGroup'({
                        allowTransformWrite: 'yes',
                        branches: [
                                'TransformGroup'({
                                        transform3D: 'Transform3D'({
                                                scale: 0.2
                                                }),
                                        branches: SimpleNodes
                                        }),
                                'TransformGroup'({
                                        transform3D: 'Transform3D'({
                                                scale: 0.12,
                                                translation: [0,0,-0.4]
                                                }),
                                        branches: [
                                                Tetrahedron
                                                ]
                                        }),
                                'TransformGroup'({
                                        transform3D: 'Transform3D'({
                                                scale: 0.12,
                                                translation: [0,0,0.4]
                                                }),
                                        branches: [
                                                Dodecahedron
                                                ]
                                        }),
                                'RotationInterpolator'({
                                        alpha: 'Alpha3D'({
                                                loopCount: -1,
                                                increasingAlphaDuration: 4000
                                                }),
                                        schedulingBounds: bounds
                                        })
                                ]
                        }),
                'Background'({
                        color: color3(1.0,1.0,1.0),
                        applicationBounds: bounds
                        }),
                'AmbientLight'({
                        lightOn: 'yes',
                        color: 'Red',
                        influencingBounds: bounds
                        }),
                'PointLight'({
                        color: 'Green',
                        position: p(3,3,3),
                        attenuation: a(1,0,0),
                        influencingBounds: bounds
                        }),
                'PointLight'({
                        color: 'Orange',
                        position: p(-2,2,2),
                        attenuation: a(1,0,0),
                        influencingBounds: bounds
                        }),
                'PickCanvas'({
                        handleMouseClicked: 'yes',
                        handleMouseEntered: 'yes',
                        handleMouseExited: 'yes',
                        handleMousePressed: 'no',
                        handleMouseReleased: 'no',
                        handleMouseDragged: 'no',
                        handleMouseMoved: 'no',
                        isPassive: 'no',
                        period: 150,
                        tolerance: 3,
                        mode: 'GEOMETRY'
                        })
                ]).
--
create_tetrahedron =
        'Shape3D'({
                label: "MyTetrahedron",
                geometry: 'IndexedTriangleArray'({
                        vertexCount: 4,
                        includeVertexPositions: 'yes',  -- COORDINATES
                        includePerVertexNormals: 'yes', -- NORMALS
                        indexCount: 12,
                        coordinates: [
                                p(1,1,1),
                                p(1,-1,-1),
                                p(-1,1,-1),
                                p(-1,-1,1)
                                ],
                        coordinateIndices: [
                                0,1,2,0,3,1,
                                1,3,2,2,3,0
                                ],
                        normals: [
                                [N,N,-(N)],
                                [N,-(N),N],
                                [-(N),-(N),-(N)],
                                [-(N),N,N]
                                ],
                        normalIndices: [
                                0,0,0,1,1,1,
                                2,2,2,3,3,3
                                ]
                        }),
                appearance: wireframe,
                allowAppearanceWrite: 'yes',
                pickingDetailLevel: 'INTERSECT_TEST'
                }) :-
        N== 1.0/?sqrt(3).
--
create_dodecahedron =
        'Shape3D'({
                label: "MyDodecahedron",
                geometry: geometryArray(
                        'GeometryInfo'({
                                primitive: 'POLYGON_ARRAY',
                                coordinates: Vertices,
                                coordinateIndices: Indices,
                                stripCounts: StripCounts,
                                generateNormals: 'yes'
                                })
                        ),
                appearance: wireframe,
                allowAppearanceWrite: 'yes',
                pickingDetailLevel: 'INTERSECT_TEST'
                }) :-
        dodecahedron_vertices(Vertices),
        Indices== [
                00,01,05,06,02, 00,02,07,08,03, 00,03,09,04,01,
                01,04,10,11,05, 02,06,12,13,07, 03,08,14,15,09,
                05,11,16,12,06, 07,13,18,14,08, 09,15,17,10,04,
                19,16,11,10,17, 19,17,15,14,18, 19,18,13,12,16],
        StripCounts== [5,5,5,5,5,5,5,5,5,5,5,5].
--
dodecahedron_vertices(Vertices):-
        dodecahedron_phi(Phi),
        Vertices== [
                p(1,1,1),
                p(0,1/Phi,Phi),
                p(Phi,0,1/Phi),
                p(1/Phi,Phi,0),
                p(-1,1,1),
                p(0,-1/Phi,Phi),
                p(1,-1,1),
                p(Phi,0,-1/Phi),
                p(1,1,-1),
                p(-1/Phi,Phi,0),
                p(-(Phi),0,1/Phi),
                p(-1,-1,1),
                p(1/Phi,-(Phi),0),
                p(1,-1,-1),
                p(0,1/Phi,-(Phi)),
                p(-1,1,-1),
                p(-1/Phi,-(Phi),0),
                p(-(Phi),0,-1/Phi),
                p(0,-1/Phi,-(Phi)),
                p(-1,-1,-1)
                ].
--
dodecahedron_phi(Value):-
        Value== 0.5*(?sqrt(5)+1).
--
mouse_clicked(NodeLabels):-!,
        con ? writeln("Mouse clicked: ",NodeLabels),
        update_appearance(NodeLabels,solid).
--
mouse_entered(NodeLabels):-!,
        con ? writeln("Mouse entered: ",NodeLabels),
        update_appearance(NodeLabels,glass).
--
mouse_exited(NodeLabels):-!,
        con ? writeln("Mouse exited: ",NodeLabels),
        update_appearance(NodeLabels,wireframe).
--
mouse_pressed(NodeLabels):-!,
        con ? writeln("Mouse pressed: ",NodeLabels).
--
mouse_released(NodeLabels):-!,
        con ? writeln("Mouse released: ",NodeLabels).
--
mouse_dragged(NodeLabels):-!,
        con ? writeln("Mouse dragged: ",NodeLabels).
--
mouse_moved(NodeLabels):-!,
        con ? writeln("Mouse moved: ",NodeLabels).
--
update_appearance([NodeLabel|Rest],Appearance):-
        set_appearance(NodeLabel,Appearance),
        update_appearance(Rest,Appearance).
update_appearance([],_).
]