/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
* Copyright 2008, 2010 Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
* This file is available and licensed under the following license:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Oracle Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package videocube;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.scene.Cursor;
import javafx.scene.CustomNode;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.effect.PerspectiveTransform;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.scene.paint.Color;
import javafx.scene.shape.Arc;
import javafx.scene.shape.ArcType;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.scene.shape.Polygon;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Alert;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javax.swing.JFileChooser;
import java.lang.Math;
def startVideoURL = "http:;
def chooser = new JFileChooser();
def r = 100;
def d = r + r;
class Point {
var x:Number;
var y:Number;
var z:Number;
function rotateX(cos, sin) {
var tmp = cos*y - sin*z;
z = cos*z + sin*y;
y = tmp;
}
function rotateY(cos, sin) {
var tmp = cos*x + sin*z;
z = cos*z - sin*x;
x = tmp;
}
function rotateZ(cos, sin) {
var tmp = cos*x - sin*y;
y = cos*y + sin*x;
x = tmp;
}
}
class Face extends CustomNode {
var number:Integer;
var ul:Point;
var ur:Point;
var lr:Point;
var ll:Point;
var background = Color.web("#ebe4ab");
var foreground = Color.web("#3b3336");
var error = true;
var media:Media;
var source:String on replace old {
if (source != old) {
error = false;
media = Media {
source: source
onError:function(error) {
this.error = true;
Alert.inform("Loading error", error.message)
}
}
}
}
def z = bind ul.z + ur.z + lr.z + ll.z;
var start:Number;
var length:Number;
def animation = Timeline {
repeatCount: Timeline.INDEFINITE
keyFrames: [
at(0s) { start => 90; length => 0 },
at(2s) { start => 90; length => 360 },
at(4s) { start => 450; length => 0 }
]
}
def animate = bind z > 0 and error on replace old {
if (animate != old) {
if (animate) {
animation.play()
} else {
animation.pause()
}
}
}
override function create() {
def pt = PerspectiveTransform {
ulx: bind d + ul.x
uly: bind d + ul.y
urx: bind d + ur.x
ury: bind d + ur.y
lrx: bind d + lr.x
lry: bind d + lr.y
llx: bind d + ll.x
lly: bind d + ll.y
}
Group {
visible: bind z > 0
content: [
Polygon {
points: bind [
pt.ulx,
pt.uly,
pt.urx,
pt.ury,
pt.lrx,
pt.lry,
pt.llx,
pt.lly
]
cursor: Cursor.HAND
blocksMouse: true
onMouseClicked:function(event) {
rotation.pause();
if (JFileChooser.APPROVE_OPTION == chooser.showOpenDialog(null)) {
source = chooser.getSelectedFile().toURI().toString()
}
rotation.play();
}
onMouseDragged:function(event) {
ax = if (-5 < event.dragY and event.dragY < 5) then 0 else - event.dragY/10000;
ay = if (-5 < event.dragX and event.dragX < 5) then 0 else event.dragX/10000;
}
},
Group {
effect: pt
visible: bind error
content: [
Rectangle {
x: -100
width: 200
y: -100
height: 200
fill: bind background
stroke: bind foreground
strokeWidth: 2
},
Circle {
radius: 85
fill: bind foreground
},
Circle {
radius: 80
fill: Color.web("#c7b668")
},
Circle {
radius: 70
fill: Color.web("#645f37")
},
Circle {
radius: 65
fill: bind background
},
Text {
x: -34
y: 40
content: bind "{number}"
fill: bind foreground
font:Font {
size: 120
embolden: true
}
},
Line {
startX: -80
endX: 80
stroke: bind foreground
strokeWidth: 2
},
Line {
startY: -80
endY: 80
stroke: bind foreground
strokeWidth: 2
},
Arc {
radiusX: 80
radiusY: 80
startAngle: bind start
length: bind length
type: ArcType.ROUND
opacity: 0.2
}
]
},
MediaView {
effect: pt
visible: bind not error
mediaPlayer:MediaPlayer {
media: bind media
autoPlay: true
repeatCount: MediaPlayer.REPEAT_FOREVER
volume: bind if (z > 0)
then 0.25*z/r
else 0
}
}
]
}
}
}
var ax = 0.002;
def cx = bind Math.cos(ax);
def sx = bind Math.sin(ax);
var ay = -0.006;
def cy = bind Math.cos(ay);
def sy = bind Math.sin(ay);
def ful = Point {
x: -r
y: -r
z: r
}
def fur = Point {
x: r
y: -r
z: r
}
def flr = Point {
x: r
y: r
z: r
}
def fll = Point {
x: -r
y: r
z: r
}
def bul = Point {
x: bind - ful.x
y: bind - ful.y
z: bind - ful.z
}
def bur = Point {
x: bind - fur.x
y: bind - fur.y
z: bind - fur.z
}
def blr = Point {
x: bind - flr.x
y: bind - flr.y
z: bind - flr.z
}
def bll = Point {
x: bind - fll.x
y: bind - fll.y
z: bind - fll.z
}
Stage {
title: "Video Cube (JavaFX sample)"
style: StageStyle.TRANSPARENT
resizable: false
scene:Scene {
fill: null
width: d + d
height: d + d
content: [
Face {
number: 1
ul: ful
ur: fur
lr: flr
ll: fll
source: startVideoURL
},
Face {
number: 2
ul: flr
ur: fur
lr: bll
ll: bul
},
Face {
number: 3
ul: bur
ur: fll
lr: flr
ll: bul
},
Face {
number: 4
ul: bll
ur: fur
lr: ful
ll: blr
},
Face {
number: 5
ul: bur
ur: blr
lr: ful
ll: fll
},
Face {
number: 6
ul: bur
ur: bul
lr: bll
ll: blr
}
]
}
}
def rotation = Timeline {
repeatCount: Timeline.INDEFINITE
keyFrames:KeyFrame {
time: 40ms
action:function() {
if (ax != 0) {
ful.rotateX(cx, sx);
fur.rotateX(cx, sx);
flr.rotateX(cx, sx);
fll.rotateX(cx, sx);
}
if (ay != 0) {
ful.rotateY(cy, sy);
fur.rotateY(cy, sy);
flr.rotateY(cy, sy);
fll.rotateY(cy, sy);
}
}
}
}
rotation.play()