222 lines
6.3 KiB
JavaScript
222 lines
6.3 KiB
JavaScript
//
|
|
// example
|
|
//
|
|
// Created by Bridget Went, 5/28/15.
|
|
// Modified by Milad Nazeri, 12/10/17
|
|
// Copyright 2015 High Fidelity, Inc.
|
|
//
|
|
// A project to build a virtual physics classroom to simulate the solar system, gravity, and orbital physics.
|
|
//
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
var planetConfig =
|
|
Script.require(Script.resolvePath('Tablet/planetDefault.json?v=' + Date.now()));
|
|
var EARTH_MODEL =
|
|
Script.resolvePath("Earth/earth.obj");
|
|
var MOON_MODEL =
|
|
Script.resolvePath("Moon/moon.FBX");
|
|
var SKYBOX =
|
|
Script.resolvePath('Background/starSky2.png');
|
|
|
|
var MESSAGES_CHANNEL = "com.highfidelity.planets.dataMessages";
|
|
|
|
var theEarth;
|
|
var theMoon;
|
|
// var theLight;
|
|
var theZone;
|
|
|
|
var update;
|
|
var center = {
|
|
x: 0,
|
|
y: 0,
|
|
z: 0 };
|
|
|
|
var ZONE_DIMENSIONS = 1000;
|
|
|
|
var radius;
|
|
var velocity;
|
|
var position;
|
|
|
|
function getGravity(){
|
|
return (
|
|
(Math.pow(planetConfig.referenceRadius.val, 3.0) /
|
|
Math.pow((planetConfig.referencePeriod.val / (2.0 * Math.PI)), 2.0)) /
|
|
planetConfig.LARGE_BODY_MASS.val);
|
|
}
|
|
function computeAcceleration(radius){
|
|
var acc =
|
|
-(getGravity() * planetConfig.LARGE_BODY_MASS.val) *
|
|
Math.pow(radius, (-2.0));
|
|
return acc;
|
|
}
|
|
function makeEarth(){
|
|
if (theEarth) {
|
|
Entities.deleteEntity(theEarth);
|
|
theEarth =
|
|
null;
|
|
}
|
|
theEarth =
|
|
Entities.addEntity({
|
|
name: 'Planet-Earth',
|
|
type: "Model",
|
|
modelURL: EARTH_MODEL,
|
|
shapeType: 'sphere',
|
|
position: center,
|
|
dimensions: { x: planetConfig.EARTH_SIZE.val,
|
|
y: planetConfig.EARTH_SIZE.val,
|
|
z: planetConfig.EARTH_SIZE.val },
|
|
angularVelocity: {
|
|
x: 0.0,
|
|
y: 0.1,
|
|
z: 0.0 },
|
|
angularDamping: planetConfig.DAMPING.val,
|
|
damping: planetConfig.DAMPING.val,
|
|
ignoreCollisions: false,
|
|
dynamic: false });
|
|
}
|
|
function makeMoon(){
|
|
if (theMoon) {
|
|
Entities.deleteEntity(theMoon);
|
|
Script.update.disconnect(update);
|
|
update =
|
|
null;
|
|
theMoon =
|
|
null;
|
|
}
|
|
var initialVelocity =
|
|
Math.sqrt((getGravity() * planetConfig.LARGE_BODY_MASS.val) / radius);
|
|
var dimensions =
|
|
planetConfig.MOON_SCALE.val *
|
|
planetConfig.referenceDiameter.val;
|
|
velocity =
|
|
Vec3.multiply(initialVelocity, Vec3.normalize({
|
|
x: 0,
|
|
y: planetConfig.VELOCITY_OFFSET_Y.val,
|
|
z: planetConfig.VELOCITY_OFFSET_Z.val }));
|
|
radius =
|
|
planetConfig.MOON_RADIUS.val *
|
|
planetConfig.referenceRadius.val;
|
|
position =
|
|
Vec3.sum(center, {
|
|
x: radius,
|
|
y: 0.0,
|
|
z: 0.0 });
|
|
theMoon =
|
|
Entities.addEntity({
|
|
type: "Model",
|
|
name: 'Planet-Moon',
|
|
modelURL: MOON_MODEL,
|
|
position: position,
|
|
shapeType: 'sphere',
|
|
dimensions: {
|
|
x: dimensions,
|
|
y: dimensions,
|
|
z: dimensions },
|
|
velocity: velocity,
|
|
angularDamping: planetConfig.DAMPING.val,
|
|
damping: planetConfig.DAMPING.val,
|
|
ignoreCollisions: false,
|
|
dynamic: false });
|
|
update =
|
|
function(deltaTime){
|
|
var between =
|
|
Vec3.subtract(position, center);
|
|
var speed =
|
|
computeAcceleration(radius) *
|
|
deltaTime;
|
|
var vel =
|
|
Vec3.multiply(speed, Vec3.normalize(between));
|
|
// Update velocity and position
|
|
velocity =
|
|
Vec3.sum(velocity, vel);
|
|
position =
|
|
Vec3.sum(position, Vec3.multiply(deltaTime, velocity));
|
|
Entities.editEntity(theMoon, {
|
|
velocity: velocity,
|
|
position: position });
|
|
};
|
|
Script.update.connect(update);
|
|
}
|
|
function makeZone(){
|
|
if (theZone) {
|
|
Entities.deleteEntity(theZone);
|
|
theZone =
|
|
null;
|
|
}
|
|
theZone =
|
|
Entities.addEntity({
|
|
name: 'Planet-Zone',
|
|
type: "Zone",
|
|
position: center,
|
|
dimensions: {
|
|
x: ZONE_DIMENSIONS,
|
|
y: ZONE_DIMENSIONS,
|
|
z: ZONE_DIMENSIONS },
|
|
backgroundMode: "skybox",
|
|
skybox: {
|
|
color: { red: 0, green: 0, blue: 0 },
|
|
url: SKYBOX } });
|
|
}
|
|
// function makeLight(){
|
|
// if (theLight) {
|
|
// Entities.deleteEntity(theLight);
|
|
// theLight =
|
|
// null;
|
|
// }
|
|
// var props = Entities.getEntityProperties(theEarth);
|
|
// var rotation = props.rotation;
|
|
// var earthVector = Quat.getFront(rotation);
|
|
//
|
|
// var lightPosition = Vec3.sum(center, Vec3.multiply(parseFloat(planetConfig.LightDistance.val), earthVector));
|
|
// theLight =
|
|
// Entities.addEntity({
|
|
// name: 'Planet-Light',
|
|
// type: 'Light',
|
|
// rotation: rotation,
|
|
// position: lightPosition,
|
|
// dimensions: {
|
|
// x: planetConfig.LightScale,
|
|
// y: planetConfig.LightScale,
|
|
// z: planetConfig.LightScale
|
|
// },
|
|
// isSpotlight: true,
|
|
// intensity: planetConfig.LightIntensity,
|
|
// color: {
|
|
// red: 255,
|
|
// green: 255,
|
|
// blue: 255 } });
|
|
// // }
|
|
function restart(){
|
|
makeEarth();
|
|
makeMoon();
|
|
// makeLight();
|
|
makeZone();
|
|
}
|
|
function CreateSimulation() {
|
|
restart();
|
|
}
|
|
|
|
CreateSimulation();
|
|
|
|
Messages.subscribe(MESSAGES_CHANNEL);
|
|
|
|
function handleMessages(channel, message, sender) {
|
|
if (channel === MESSAGES_CHANNEL) {
|
|
var data = JSON.parse(message);
|
|
planetConfig[data.id].val = data.value;
|
|
restart();
|
|
}
|
|
}
|
|
|
|
Messages.messageReceived.connect(handleMessages);
|
|
|
|
function scriptEnding() {
|
|
Entities.deleteEntity(theEarth);
|
|
Entities.deleteEntity(theMoon);
|
|
Entities.deleteEntity(theZone);
|
|
// Entities.deleteEntity(theLight);
|
|
}
|
|
|
|
Script.scriptEnding.connect(scriptEnding);
|