<!--
/*
 * 3dhtml Example :: Heart3D
 * Version 1.0, 20/11/2001
 * 
 * Copyright (c) 2001 by Netzministerium.de
 * Written by Till Nagel and René Sander.
 * Distributed under the terms of the GNU Lesser General Public. (See licence.txt for details)
 */
-->
<html>
<head>
<title>3dhtml Example :: Heart 3D</title>
<!-- helper libs -->
<script language="JavaScript" src="../js/LyrObj.js"></script>
<script language="JavaScript" src="../js/ClipButton.js"></script>
<!-- core 3dhtml lib -->
<script language="JavaScript" src="../js/3dhtml.js"></script>
<!-- mouse scale modulator -->
<script language="JavaScript" type="text/javascript" src="../js/MouseModulator.js"></script>
<script language="JavaScript" src="../js/HeartBeatModulator.js"></script>
<!-- Color Utils for the points -->
<script language="JavaScript" src="../js/ColorUtil.js"></script>
<!-- ColorRectMaterial -->
<script language="JavaScript" src="../js/materials.js"></script>
<script language="javascript">
<!-- // (c) 2001 Till Nagel, till@netzministerium.de & Rene Sander, rene@netzministerium.de

// ---------------------------------------------------------------------------
// MATERIALS

var redBallCBMAterial = createClipButtonMaterial("images/balls.gif", 20, 180, 20, 20, 9);
var blueBallCBMAterial = createClipButtonMaterial("images/balls_blue.gif", 20, 180, 20, 20, 9);


// ---------------------------------------------------------------------------
// HEART MODEL

// creates heart model with red balls
var heartModel = new Model("heart", redBallCBMAterial);

// defines model points.
// The model's points have to be defined before the respective code is written into the document.
heartModel.setPoints(createHeartModelPoints());

// ---------------------------------------------------------------------------
// HEART SHADOW MODEL

// creates heart shadow model with gray balls
var heartShadowModel = new Model("heartShadow", blueBallCBMAterial);

// defines model points.
heartShadowModel.setPoints(createHeartModelPoints());

// ---------------------------------------------------------------------------
// MODULATORS

// modulator to rotate the model dependent on mouse interactions
var myMouseModulator = new MouseModulator("myMouseModulator");
// modulator to change the size of the model dependent on sin()
var myHeartBeatModulator = new HeartBeatModulator(15);

// ---------------------------------------------------------------------------

// the matrix to transform the heart into its shadow 
var reflectionMatrix = new Matrix();

function initOnLoad() {
	fixNetscape();
	// >> begin to work with the model etc.

	heartModel.assignLayers();
	heartShadowModel.assignLayers();
	
	
	//OFFSET_Y_3DHTML = 180;
	// inits reflectionMatrix 
	reflectionMatrix.translate(0, -300, 0);
	reflectionMatrix.scale(1, 1, -1);
	reflectionMatrix.rotateX(Math.PI);
	
	// creates and inits matrix to initialize the model
	var initMatrix = new Matrix();
	initMatrix.scale(20, 20, 20);
	initMatrix.rotateX(Math.PI);
	
	// transforms heart (and shadow) model
	heartModel.transform(initMatrix);

	
	// copies the current positions of the points from the heart model
	heartShadowModel.copyPointsFrom(heartModel);
	// transforms the heart as it is its own shadow
	heartShadowModel.transform(reflectionMatrix);
		
	// >> first draw call to the model
	heartModel.draw();
	heartShadowModel.draw();
	
	// starts animation
	animate();
}

// try: used to store all heartBeat scale transformations
// to undo them. (OpenGL technique)
var heartBeatStackMatrix = new Matrix();

/*
 * The main animate method. Calls itself repeatedly.
 */
function animate() {
	var delay = 10;
	
	// animates the modulator to spin the heart
	myMouseModulator.animate();
	
	// animates the modulator to beat the heart
	myHeartBeatModulator.animate();

	
	// animates HeartModel ----------------------------------------

	// transforms the heart depending on mouse movements
	//  and on heart beat function
	var myMatrix = myMouseModulator.getMatrix();
	myMatrix.compose(myHeartBeatModulator.getMatrix());
	heartModel.transform(myMatrix);


	// updates display
	heartModel.draw();
	
	
	// animates HeartShadowModel ----------------------------------------
	
	// copies the current positions of the points from the heart model
	heartShadowModel.copyPointsFrom(heartModel);
	// transforms the heart as it is its own shadow
	heartShadowModel.transform(reflectionMatrix);

	// updates display
	heartShadowModel.draw();

	
	// calls itself with an delay to decouple client computer speed from the animation speed.
	// result: the animation is as fast as possible.
	setTimeout("animate()", delay);
}


// event handling
document.onmousemove = mouseMoveHandler;
document.onmousedown = mouseDownHandler;
document.onmouseup = mouseUpHandler;
if (ns) document.captureEvents(Event.MOUSEMOVE | Event.MOUSEDOWN | Event.MOUSEUP);

/*
 * The mouse handlers in this document must call the modulator's handlers.
 * To be able to use a mouse modulator and to do your own stuff.
 */
function mouseMoveHandler(e) {

	// calls move handler of the mouse modulator
	myMouseModulator.move(e);

	/*
	// other stuff, e.g.
	if (ns || ie) {
			mouseX = (ns) ? e.pageX : event.x;
			mouseY = (ns) ? e.pageY : event.y;
	}
	*/

	return !ie;
}
  
function mouseDownHandler(e) {
	// calls down handler of the mouse modulator
	myMouseModulator.down(e);
}

function mouseUpHandler(e) {
	// calls up handler of the mouse modulator
	myMouseModulator.up(e);
}



// ---------------------------------------------------------------------------

function createHeartModelPoints() {
	// the heart model
	return new Array(
		new Point3D(0.0, 3.0, 1.0, 0),
		new Point3D(1.0, 4.0, 1.0, 0),
		new Point3D(2.4, 4.2, 1.5, 0),
		new Point3D(3.75, 3.5, 2.0, 0),
		new Point3D(3.7, 1.5, 2.0, 0),
		new Point3D(2.0, -2.0, 1.5, 0),
		new Point3D(0.0, -4.0, 0.5, 0),
		
		new Point3D(-0.0, 3.0, 1.0, 0),
		new Point3D(-1.0, 4.0, 1.0, 0),
		new Point3D(-2.4, 4.2, 1.5, 0),
		new Point3D(-3.75, 3.5, 2.0, 0),
		new Point3D(-3.7, 1.5, 2.0, 0),
		new Point3D(-2.0, -2.0, 1.5, 0),
		new Point3D(-0.0, -4.0, 0.5, 0),
		
		new Point3D(0.0, 3.0, -1.0, 0),
		new Point3D(1.0, 4.0, -1.0, 0),
		new Point3D(2.4, 4.2, -1.5, 0),
		new Point3D(3.75, 3.5, -2.0, 0),
		new Point3D(3.7, 1.5, -2.0, 0),
		new Point3D(2.0, -2.0, -1.5, 0),
		new Point3D(0.0, -4.0, -0.5, 0),
		
		new Point3D(-0.0, 3.0, -1.0, 0),
		new Point3D(-1.0, 4.0, -1.0, 0),
		new Point3D(-2.4, 4.2, -1.5, 0),
		new Point3D(-3.75, 3.5, -2.0, 0),
		new Point3D(-3.7, 1.5, -2.0, 0),
		new Point3D(-2.0, -2.0, -1.5, 0),
		new Point3D(-0.0, -4.0, -0.5, 1)
	);
}

// -->
</script>
<style type="text/css">
<!--
	body {
		background-image:url('images/bgheart3d.gif');
		background-repeat:repeat-x;
		background-color:#C7E0FF;
	}
// -->
</style>
</head>

<body onload="initOnLoad()" bottommargin="0" leftmargin="0" marginheight="0" marginwidth="0" rightmargin="0" topmargin="0" style="height:100%">
<!-- layer to bugfix netscape -->
<div id="fixnetscape" style="position:absolute;visibility:hidden"></div>

<div id="sym" style="position:absolute; left:600px; top:430px; background-color:red"><img src="images/sym.gif" width="155" height="145" alt="" border="0"></div>

<script language="JavaScript" type="text/javascript">
<!-- // (c) 2001 Till Nagel, till@netzministerium.de & Rene Sander, rene@netzministerium.de

// MANDATORY: INSERTION OF HTML PART INTO PAGE
// creates the HTML code representing the model's points
// NB: This is written directly into the page from within the method	
heartModel.createPointCode();

heartShadowModel.createPointCode();
// -->
</script>

</body>
</html>


Syntax highlighted by Code2HTML, v. 0.9, modified by Netzministerium, 2001.