Closed GoogleCodeExporter closed 9 years ago
Here is the full code
I show you the code hoping you answer back with a solution
turnLeft = false;
turnRight = false;
g_mouseLocked = false;
deltaX = 1;
deltaY = 1;
moveForward = false;
moveBackward = false;
strafeLeft = false;
strafeRight = false;
forwardVelocity = 3;
run = false;
rolling = 0;
var lastTurn = 0;
camera1 = true;
camera2 = false;
var avatar = new Array("");
var initScreen = false;
INITIAL_CAMERA_ALTITUDE = 1.7; // Roughly 6 feet tall
cameraAltitude = INITIAL_CAMERA_ALTITUDE;
var MODEL_URL = new
Array("http://localhost/tankbody.kmz","http://localhost/tankwhell.kmz","http://l
ocalhost/tankcanion.kmz");
//----------------------------------------------------------------------------
// Utility Functions
//----------------------------------------------------------------------------
// Keep an angle in [-180,180]
function fixAngle(a) {
while (a < -180) {
a += 360;
}
while (a > 180) {
a -= 360;
}
return a;
}
//----------------------------------------------------------------------------
// Input Handlers
//----------------------------------------------------------------------------
function mouseDown(e) {
var mouseButton = e.getButton();
var hitGlobe = e.getDidHitGlobe();
if (mouseButton == 0 && hitGlobe == 1 && initScreen ){
goUp = true;
}
if(mouseButton==2 && hitGlobe==1) {
goDown = true;
}
if (!initScreen){
g_mouseLocked = !g_mouseLocked;
initScreen = true;
tiltDown = false;
tiltUp = false;
turnLeft = false;
turnRight = false;
}
}
function mouseUp(e){
var mouseButton = e.getButton();
var hitGlobe = e.getDidHitGlobe();
if(mouseButton==2 && hitGlobe==1) {
goDown = false;
}
if(mouseButton == 0 && hitGlobe == 1) {
goUp = false;
}
}
function eventHandler(event) {
var x=event.getClientX();
var y=event.getClientY();
var screenX = event.getScreenX();
var screenY = event.getScreenY();
var text = 'Click';
myWidth = window.innerWidth/5;
myHeight = window.innerHeight/7;
maxX = 2*myWidth;
maxY = 2*myHeight;
if (g_mouseLocked) {
if (x<2*myWidth){
turnRight = false;
deltaX = Math.exp((((3*myWidth-x)/maxX)-1)*3); // (((3*myWidth-x)/maxX)+0.02)*3;
turnLeft= true;
}
else if (x>3*myWidth) {
turnLeft = false;
deltaX = Math.exp((((x-3*myWidth)/maxX)-0.5)*3);//(((x-3*myWidth)/maxX)+0.02)*3;
turnRight=true;
}
else{
turnLeft = false;
turnRight = false;
}
if (y<2*myHeight){
tiltDown = false;
deltaY = (((2*myHeight-y)/maxY)+0.5);
tiltUp=true;
}
else if (y>5*myHeight) {
tiltUp = false;
deltaY = (((y-5*myHeight)/maxY)+0.5);
tiltDown = true;
}
else{
tiltDown = false;
tiltUp=false;
}
}
event.returnValue = false;
}
function keyDown(event) {
if (!event) {
event = window.event;
}
if (event.keyCode == 37) { // Turn Left.
turnLeft = true;
event.returnValue = false;
} else if (event.keyCode == 39) { // Turn Right.
turnRight = true;
event.returnValue = false;
} else if (event.keyCode == 38) { // Tilt Up.
tiltUp = true;
event.returnValue = false;
} else if (event.keyCode == 40) { // Tilt Down.
tiltDown = true;
event.returnValue = false;
} else if (event.keyCode == 65) { // Strafe Left.
strafeLeft = true;
event.returnValue = false;
} else if (event.keyCode == 68) { // Strafe Right.
strafeRight = true;
event.returnValue = false;
} else if (event.keyCode == 87) { // Move Forward.
moveForward = true;
event.returnValue = false;
} else if (event.keyCode == 83) { // Move Forward.
moveBackward = true;
event.returnValue = false;
} else if (event.keyCode == 32) { // Spacebar
run=true;
event.returnValue = false;
} else if (event.keyCode == 49) { // Camera 1
camera1 = true;
event.returnValue = false;
} else if (event.keyCode == 50) { // Camera 2
camera2 = true;
event.returnValue = false;
} else if (event.keyCode == 27) { // escape
initScreen = false;
g_mouseLocked = false;
}
else {
return true;
}
return false;
}
function keyUp(event) {
if (!event) {
event = window.event;
}
if (event.keyCode == 37) { // Left.
turnLeft = false;
event.returnValue = false;
} else if (event.keyCode == 39) { // Right.
turnRight = false;
event.returnValue = false;
} else if (event.keyCode == 38) { // Up.
tiltUp = false;
event.returnValue = false;
} else if (event.keyCode == 40) { // Down.
tiltDown = false;
event.returnValue = false;
} else if (event.keyCode == 65) { // Strafe Left.
strafeLeft = false;
event.returnValue = false;
} else if (event.keyCode == 68) { // Strafe Right.
strafeRight = false;
event.returnValue = false;
} else if (event.keyCode == 87) { // Move Forward.
moveForward = false;
event.returnValue = false;
} else if (event.keyCode == 83) { // Move Forward.
moveBackward = false;
event.returnValue = false;
} else if (event.keyCode == 32) { // Run
run = false;
event.returnValue = false;
} else if (event.keyCode == 49) { // Camera1
camera1 = false;
event.returnValue = false;
} else if (event.keyCode == 50) { // Camera2
camera2 = false;
event.returnValue = false;
} else if (event.keyCode == 27) { // escape
}
return false;
}
function TankCam() {
var me = this;
me.localAnchorLla = [37.77976, -122.418307, 0];
me.localAnchorCartesian = V3.latLonAltToCartesian(me.localAnchorLla);
// Heading, tilt angle is relative to local frame
me.headingAngle = 0*Math.PI/180;
me.tiltAngle = 0;
me.roll = 0;
// Initialize the time
me.lastMillis = (new Date()).getTime();
// Used for bounce.
me.distanceTraveled = 0;
// prevent mouse navigation in the plugin
ge.getOptions().setMouseNavigationEnabled(true);
for (i=0; i<MODEL_URL.length; i++){
window.google.earth.fetchKml(ge, MODEL, function(obj) { me.finishInit(obj); });
}
google.earth.addEventListener(ge, "frameend",
function() { me.update(); });
}
TankCam.prototype.finishInit = function(kml){
var me = this;
me.placemark = kml.getFeatures().getChildNodes().item(1);
me.model = me.placemark.getGeometry();
me.orientation = me.model.getOrientation();
me.location = me.model.getLocation();
me.model.setAltitudeMode(ge.ALTITUDE_RELATIVE_TO_SEA_FLOOR);
me.orientation.setHeading(0);
me.model.setOrientation(me.orientation);
avatar = me.placemark;
ge.getFeatures().appendChild(avatar);
}
TankCam.prototype.updateOrientation = function(dt) {
var me = this;
// Based on dt and input press, update turn angle.
if (turnLeft || turnRight) {
var turnSpeed = 20.0 * deltaX; // radians/sec
if (turnLeft)
turnSpeed *= -1.0;
me.headingAngle += turnSpeed * dt * Math.PI / 180.0;
******** HERE IS THE CRAZY STUFF I'VE TRYED TO SET A DIFFERENT HEADING OF THE THREE OBJECTS **************
******* I KNOW IS WRONG BECAUSE I LEAVE THE IMPOSIBLE, DON'T CARE ABOUT THIS CODE ****************************
//for (i=0;i<=avatar.length;i++){
// me.model[1] = avatar[1].getGeometry();
// me.orientation[1] = me.model[1].getOrientation();
// me.orientation[1].setHeading(me.headingAngle * 180 / Math.PI);
// avatar[i].orientation.setHeading(me.headingAngle * 180 / Math.PI);
// avatar[i].model.orientation.setHeading(me.headingAngle * 180 / Math.PI);
me.orientation.setHeading(me.headingAngle * 180 / Math.PI);
//}
}
********************************************************************************
*******************************
// TODO (1 - t) * a + t * b formula del lerp
// tilting
if (tiltUp || tiltDown) {
var tiltSpeed = 10.0 * deltaY; // radians/sec
if (tiltDown)
tiltSpeed *= -1.0;
me.tiltAngle += tiltSpeed * dt * Math.PI / 180.0;
// Clamp
var tiltMax = 90.0 * Math.PI / 180.0;
var tiltMin = -90.0 * Math.PI / 180.0;
if (me.tiltAngle > tiltMax){
me.tiltAngle = tiltMax;
}
if (me.tiltAngle < tiltMin){
me.tiltAngle = tiltMin;
}
}
}
TankCam.prototype.updatePosition = function(dt) {
var me = this;
// Convert local lat/lon to a global matrix. The up vector is
// vector = position - center of earth. And the right vector is a vector
// pointing eastwards and the facing vector is pointing towards north.
var localToGlobalFrame = M33.makeLocalToGlobalFrame(me.localAnchorLla);
// Move in heading direction by rotating the facing vector around
// the up vector, in the angle specified by the heading angle.
// Strafing is similar, except it's aligned towards the right vec.
var headingVec = V3.rotate(localToGlobalFrame[1], localToGlobalFrame[2],
-me.headingAngle);
var rightVec = V3.rotate(localToGlobalFrame[0], localToGlobalFrame[2],
-me.headingAngle);
// Calculate strafe/forwards
var strafe = 0;
if (strafeLeft || strafeRight) {
var strafeVelocity = 4;
if (strafeLeft)
strafeVelocity *= -1;
strafe = strafeVelocity * dt;
}
var forward = 0;
if (moveForward || moveBackward) {
var forwardVelocity = 4;
if (run)
forwardVelocity = 12;
if (run) forwardVelocity = forwardVelocity * 5;
if (moveBackward)
forwardVelocity *= -1;
forward = forwardVelocity * dt;
}
cameraAltitude = Math.max(0, cameraAltitude);
me.distanceTraveled += forward;
// Add the change in position due to forward velocity and strafe velocity
me.localAnchorCartesian = V3.add(me.localAnchorCartesian,
V3.scale(rightVec, strafe));
me.localAnchorCartesian = V3.add(me.localAnchorCartesian,
V3.scale(headingVec, forward));
// Convert cartesian to Lat Lon Altitude for camera setup later on.
me.localAnchorLla = V3.cartesianToLatLonAlt(me.localAnchorCartesian);
}
TankCam.prototype.updateCamera = function() {
var me = this;
var lla = me.localAnchorLla;
lla[2] = ge.getGlobe().getGroundAltitude(lla[0], lla[1]);
// Update camera position. Note that tilt at 0 is facing directly downwards.
// We add 90 such that 90 degrees is facing forwards.
var la = ge.createCamera('');
la.set(me.localAnchorLla[0], me.localAnchorLla[1],
cameraAltitude,
ge.ALTITUDE_RELATIVE_TO_SEA_FLOOR,
fixAngle(me.headingAngle * 180 / Math.PI), /* heading */
me.tiltAngle * 180 / Math.PI + 90, /* tilt */
me.roll /* altitude is constant */
);
ge.getView().setAbstractView(la);
};
TankCam.prototype.update = function() {
var me = this;
ge.getWindow().blur();
// Update delta time (dt in seconds)
var now = (new Date()).getTime();
var dt = (now - me.lastMillis) / 1000.0;
if (dt > 0.25) {
dt = 0.25;
}
me.lastMillis = now;
// Update orientation and then position of camera based
// on user input
me.updateOrientation(dt);
me.updatePosition(dt);
// Update camera
me.updateCamera();
};
PROBABLY YOU'LL SEE THERE'S A FEW THINGS MISSING LIKE {},; OR WHATEVER STUFF
LIKE THIS BUT IF YOU TRY TO FIX IT YOU'LL SEE THAT THERE'S NO FULL MOVEMENT OF
ALL PARTS, I'VE TRYED EVERYTHING AND NO CHANGES.
Original comment by vrt...@gmail.com
on 19 Feb 2011 at 10:20
I'm not sure if I understand the issue. If these are a group of geometries, you
should be able to add them as siblings to the DOM and then move them via their
parent node. Do you have a link where your example can be seen in action?
Original comment by bcke...@google.com
on 17 May 2011 at 12:28
actually, sorry, my last statement is incorrect. You would have to transform
each part separately and then update each position manually. This is slightly
awkward in Earth because the KML DOM is specifically *not* a spatial
scenegraph, which is the same reason that the Earth API does not have this
functionality.
However, this is pretty standard code in just about any scenegraph library, so
should be easily obtainable for this purpose. I suggest adapting that code for
this purpose, then treating the KmlModel objects as write-only views, using
setLocation() and setOrientation().
The Earth Utility Library may also be helpful:
http://code.google.com/p/earth-api-utility-library/
Original comment by bcke...@google.com
on 17 May 2011 at 12:40
Original issue reported on code.google.com by
vrt...@gmail.com
on 18 Feb 2011 at 1:13