#VRML V2.0 utf8
	
	WorldInfo {
	
	title "Squash rackets"
	
	}
	
	# 視点
	Viewpoint {
	
	position 0.0 1.7 10
	description "initial"
	
	}
	Viewpoint {
	
	position 0 7.8 9.7
	orientation -1 0 0 .68
	description "Bird"
	
	}
	#Inline { url "getVp.wrl"}
	
	# ナビゲーション情報
	NavigationInfo {
	
	type "EXAMINE"
	headlight FALSE
	
	}
	
	# 背景
	Background {
	
	skyAngle [ 1.57 1.571 ]
	skyColor [ 0.0 0.2 1.0, 0.5 0.8 1.0, 0.6 0.3 0.0 ]
	
	}
	
	# 照明
	PointLight {
	
	location 1 2.5 6
	
	}
	PointLight {
	
	location -1 2.5 6
	
	}
	
	# コート床
	Transform {
	
	translation 0 -0.005 0
	children [
	
	Shape {
	
	appearance Appearance {
	
	material Material {
	
	diffuseColor 1.0 0.7 0.3
	
	}
	
	}
	geometry Box {
	
	size 5 0.01 10
	
	}
	
	}
	
	]
	
	}
	# コート天井
	Transform {
	
	translation 0 3.05 0
	children [
	
	Shape {
	
	appearance Appearance {
	
	material Material {
	
	emissiveColor 0.3 0.3 0.27
	diffuseColor 1.0 0.9 0.7
	transparency 0.7
	
	}
	
	}
	geometry Box {
	
	size 5 0.1 10
	
	}
	
	}
	
	]
	
	}
	# コート壁(奥)
	Transform {
	
	translation 0 1.5 -5.05
	children [
	
	Shape {
	
	appearance DEF Court-Ap Appearance {
	
	material Material {
	
	diffuseColor 0.2 0.9 0.7
	
	}
	
	}
	geometry Box {
	
	size 5.2 3.2 0.1
	
	}
	
	}
	
	]
	
	}
	# コート壁(左)
	Transform {
	
	translation -2.55 1.55 0
	children [
	
	DEF SideWall-Sp Shape {
	
	appearance USE Court-Ap
	geometry Box {
	
	size 0.1 3.1 10
	
	}
	
	}
	
	]
	
	}
	# コート壁(右)
	Transform {
	
	translation 2.55 1.55 0
	children USE SideWall-Sp
	
	}
	
	# ボール
	DEF Ball-Tf Transform {
	
	children [
	
	Shape {
	
	appearance Appearance {
	
	material Material {
	
	diffuseColor 1 0 0
	
	}
	
	}
	geometry DEF Ball Sphere {
	
	radius 0.2
	
	}
	
	}
	DEF Ball-ThS TouchSensor {}
	
	]
	
	}
	
	# ボールの影
	DEF BallShadow-Tf Transform {
	
	scale 1 0.01 1
	children [
	
	Shape {
	
	appearance Appearance {
	
	material Material {
	
	diffuseColor 0 0 0
	
	}
	
	}
	geometry USE Ball
	
	}
	
	]
	
	}
	
	# ラケット
	DEF Racket-Tf Transform {
	
	translation 0 1 5.2
	children [
	
	Shape {
	
	appearance Appearance {
	
	material Material {
	
	diffuseColor 1 1 0
	transparency 0.3
	
	}
	
	}
	geometry Box {
	
	size 1 1 0.1
	
	}
	
	}
	DEF Racket-PlS PlaneSensor {
	
	offset 0 1 5.2
	minPosition -2 0.5
	maxPosition  2 2.5
	
	}
	
	]
	
	}
	# ラケットの影
	DEF RacketShadow-Tf Transform {
	
	translation 0 0 5.2
	children [
	
	Shape {
	
	appearance Appearance {
	
	material Material {
	
	diffuseColor 0 0 0
	
	}
	
	}
	geometry Box {
	
	size 1 0.001 0.1
	
	}
	
	}
	
	]
	
	}
	
	
	# タイムセンサー
	DEF TiS TimeSensor {
	
	loop TRUE
	
	}
	
	# スクリプト
	DEF Sc Script {
	
	eventIn SFTime touchTime_Ball
	eventIn SFFloat set_fraction
	eventIn SFVec3f translation_Racket
	eventOut SFVec3f posBall            # ボールの位置
	eventOut SFVec3f posBallShadow      # ボールの影の位置
	eventOut SFVec3f posRacketShadow    # ラケットの影の位置
	field SFVec3f moveVec 0 0 0         # ボールの移動ベクトル
	field SFFloat oldF 0                # 前回イベント時の fraction_changed の値
	field SFVec3f posRacket 0 0 0	    # ラケットの位置
	field SFBool active FALSE           # ボールを動かすか否か
	field SFFloat speed 5.0             # ボールのスピード
	field SFBool isCortona FALSE        # 実行しているブラウザーが Cortona か否か
	url "javascript:
	
	
	function initialize () {
	
	
	// ボールとその影の位置をセットする。
	posBall.x = 2 * Math.random() - 1;
	posBall.y = 2 * Math.random() + 0.5;
	posBall.z = 5;
	
	posBallShadow.x = posBall.x;
	posBallShadow.y = 0;
	posBallShadow.z = posBall.z;
	
	// 実行中のブラウザーが Cortona か調べる。
	isCortona = (Browser.getName() == 'Cortona VRML Client');
	
	
	}
	
	function touchTime_Ball () {
	
	
	// 既に active が true (ボールが動いている)ならば、この関数を終える。
	if (active) return;
	
	// active を true にセットする。(ボールを動かす)
		active = true;
	
	// ボールの移動ベクトルをセットする。
		moveVec.x = Math.random() * 2 - 1;
		moveVec.y = Math.random() * 2 - 1;
		moveVec.z = -1;
	
	// ボールのスピードを 5.0 とする。
	speed = 5.0;
	moveVec = moveVec.normalize().multiply(speed);
	
	
	}
	
	function set_fraction (f) {
	
	
	// fraction の変化量を得る。
	var df = f - oldF;
	if ( df < 0 ) df++;
	oldF = f;
	
	// ブラウザーがCortonaならば、df にフレームレートの逆数を入れる。
	if (isCortona) {
	
	var fps = Browser.getCurrentFrameRate();
	if ( fps > 0.0 ) df = 1 / fps;
	
	}
	
	// active が false ならば、この関数を終えてボールを動かさないようにする。
	if ( !active ) return;
	
	// ボールを移動させる。
		posBall = moveVec.multiply(df).add(posBall);
	
	// ボールがコートからはみ出ているならば、
	// ボールの進行方向を変えて、ボールをコートの内側に置く。
	if ( posBall.x < -2.3 || posBall.x > 2.3 ) {
	
	
	moveVec.x = -moveVec.x;
	posBall.x = Math.max( -2.3, Math.min( 2.3 , posBall.x ));
	
	
	}
	
	if ( posBall.y < 0.2 || posBall.y > 2.8 ) {
	
	
	moveVec.y = -moveVec.y;
	posBall.y = Math.max( 0.2, Math.min( 2.8 , posBall.y ));
	
	
	}
	
	if ( posBall.z < -4.8 ) {
	
	
	moveVec.z = -moveVec.z;
	posBall.z = Math.max( -4.8 , posBall.z );
	
	
	}
	
	// ボールが手前に帰ってきたならば、ラケットにボールが当たっているか判断させる。
	if ( posBall.z > 5.0 ) {
	
	
	judgeCollisionWithRacket ();
		posBall.z = 5.0;
	
	
	}
	
	// ボールの影の位置をセットする。
	posBallShadow.x = posBall.x;
	posBallShadow.y = 0;
	posBallShadow.z = posBall.z;
	
	
	}
	
	function judgeCollisionWithRacket () {
	
	
	// ボールとラケットの中心位置との距離をx成分とy成分について得る。
	var dx = Math.abs ( posRacket.x - posBall.x );
	var dy = Math.abs ( posRacket.y - posBall.y );
	
	if ( dx < 0.7 && dy < 0.7 ) {
	
	
	// ボールがラケットに当たっているならば、ボールの進行方向を変える。
		moveVec.z = -moveVec.z;
	
	// ボールがラケットに当たる度に、ボールのスピードを少しずつ上げる。
		speed += 0.2;
		moveVec = moveVec.normalize().multiply(speed);
	
	
	}
	
	// ボールがラケットから外れているならば、 active を false にしてボールを止める。
	else active = false;
	
	
	}
	
	function translation_Racket (val) {
	
	
	// ラケットの位置を得る。
		posRacket = val;
	
	// ラケットの影の位置をセットする。
	posRacketShadow.x = val.x;
	posRacketShadow.y = 0;
	posRacketShadow.z = val.z;
	
	
	}
	
	
	"
	
	}
	
	# ラケットとその影の移動
	ROUTE Racket-PlS.translation_changed TO Racket-Tf.translation
	ROUTE Sc.posRacketShadow TO RacketShadow-Tf.translation
	
	# ボールをクリックしたことをスクリプトに知らせる
	ROUTE Ball-ThS.touchTime TO Sc.touchTime_Ball
	
	# タイムセンサーの経過をスクリプトへ送る
	ROUTE TiS.fraction_changed TO Sc.set_fraction
	
	# ボールとその影の位置の移動
	ROUTE Sc.posBall TO Ball-Tf.translation
	ROUTE Sc.posBallShadow TO BallShadow-Tf.translation
	
	# ラケットの位置をスクリプトに送る
	ROUTE Racket-PlS.translation_changed TO Sc.translation_Racket