346 lines
No EOL
15 KiB
JavaScript
346 lines
No EOL
15 KiB
JavaScript
(function() {
|
|
var soccerDebug = function() {
|
|
var self = this;
|
|
this.debugLines = {};
|
|
this.debugSpheres = {};
|
|
this.debugCubes = {};
|
|
this.showDebugShapes = false;
|
|
this.showSolidShapes = false;
|
|
|
|
this.setDebugCube = function(cubeName, cubePosition, cubeRotation, cubeDimensions, shapeColor, forceRendering) {
|
|
var doRender = self.showDebugShapes || forceRendering;
|
|
if (!doRender) return;
|
|
var position = cubePosition ? cubePosition : {x: 0, y: 0, z: 0};
|
|
var rotation = cubeRotation ? cubeRotation : {x: 0, y: 0, z: 0, w: 0};
|
|
var dimensions = cubeDimensions ? cubeDimensions : {x: 1, y: 1, z: 1};
|
|
var color = shapeColor !== undefined ? shapeColor : { red: 0, green: 255, blue: 255 };
|
|
if (self.debugCubes[cubeName] !== undefined) {
|
|
Overlays.editOverlay(self.debugCubes[cubeName], {
|
|
position: position,
|
|
rotation: rotation,
|
|
dimensions: dimensions,
|
|
color: color,
|
|
solid: self.showSolidShapes,
|
|
visible: true
|
|
});
|
|
} else {
|
|
self.debugCubes[cubeName] = Overlays.addOverlay("cube", {
|
|
position: position,
|
|
rotation: rotation,
|
|
dimensions: dimensions,
|
|
color: color,
|
|
solid: self.showSolidShapes,
|
|
visible: true
|
|
});
|
|
}
|
|
};
|
|
|
|
this.setDebugLine = function(lineName, startPosition, endPosition, shapeColor, forceRendering) {
|
|
var doRender = self.showDebugShapes || forceRendering;
|
|
if (!doRender) return;
|
|
var start = startPosition ? startPosition : {x: 0, y: 0, z: 0};
|
|
var end = endPosition ? endPosition : {x: 0, y: 1, z: 0};
|
|
var color = shapeColor ? shapeColor : { red: 0, green: 255, blue: 255 };
|
|
if (self.debugLines[lineName] !== undefined) {
|
|
Overlays.editOverlay(self.debugLines[lineName], {
|
|
color: color,
|
|
start: start,
|
|
end: end,
|
|
visible: true
|
|
});
|
|
} else {
|
|
self.debugLines[lineName] = Overlays.addOverlay("line3d", {
|
|
color: color,
|
|
start: start,
|
|
end: end,
|
|
visible: true
|
|
});
|
|
}
|
|
};
|
|
|
|
this.setDebugSphere = function(sphereName, pos, diameter, shapeColor, forceRendering) {
|
|
var doRender = self.showDebugShapes || forceRendering;
|
|
if (!doRender) return;
|
|
var scale = diameter ? diameter : 0.01;
|
|
var color = shapeColor ? shapeColor : { red: 255, green: 0, blue: 255 };
|
|
if (self.debugSpheres[sphereName] !== undefined) {
|
|
Overlays.editOverlay(self.debugSpheres[sphereName], {
|
|
color: color,
|
|
position: pos,
|
|
scale: {x:scale, y:scale, z:scale},
|
|
solid: self.showSolidShapes,
|
|
visible: true
|
|
});
|
|
} else {
|
|
self.debugSpheres[sphereName] = Overlays.addOverlay("sphere", {
|
|
color: color,
|
|
position: pos,
|
|
scale: {x:scale, y:scale, z:scale},
|
|
solid: self.showSolidShapes,
|
|
visible: true
|
|
});
|
|
}
|
|
};
|
|
|
|
this.deleteSphere = function(name) {
|
|
Overlays.deleteOverlay(self.debugSpheres[name]);
|
|
self.debugSpheres[name] = undefined;
|
|
};
|
|
|
|
this.deleteLine = function(name) {
|
|
Overlays.deleteOverlay(self.debugLines[name]);
|
|
self.debugLines[name] = undefined;
|
|
};
|
|
|
|
this.deleteCube = function(name) {
|
|
Overlays.deleteOverlay(self.debugCubes[name]);
|
|
self.debugCubes[name] = undefined;
|
|
};
|
|
|
|
this.cleanup = function() {
|
|
for (var lineName in self.debugLines) {
|
|
if (lineName !== undefined) {
|
|
self.deleteLine(lineName);
|
|
}
|
|
}
|
|
for (var sphereName in self.debugSpheres) {
|
|
if (sphereName !== undefined) {
|
|
self.deleteSphere(sphereName);
|
|
}
|
|
}
|
|
for (var cubeName in self.debugCubes) {
|
|
if (cubeName!== undefined) {
|
|
self.deleteCube(cubeName);
|
|
}
|
|
}
|
|
self.debugLines = {};
|
|
self.debugSpheres = {};
|
|
self.debugCubes = {};
|
|
};
|
|
|
|
this.setVisible = function(isVisible) {
|
|
self.showDebugShapes = isVisible;
|
|
for (var lineName in self.debugLines) {
|
|
if (lineName !== undefined) {
|
|
Overlays.editOverlay(self.debugLines[lineName], {
|
|
visible: isVisible
|
|
});
|
|
}
|
|
}
|
|
for (var sphereName in self.debugSpheres) {
|
|
if (sphereName !== undefined) {
|
|
Overlays.editOverlay(self.debugSpheres[sphereName], {
|
|
visible: isVisible
|
|
});
|
|
}
|
|
}
|
|
};
|
|
|
|
this.setSolid = function(isSolid) {
|
|
self.showSolidShapes = isSolid;
|
|
for (var lineName in self.debugLines) {
|
|
if (lineName !== undefined) {
|
|
Overlays.editOverlay(self.debugLines[lineName], {
|
|
solid: isSolid
|
|
});
|
|
}
|
|
}
|
|
for (var sphereName in self.debugSpheres) {
|
|
if (sphereName !== undefined) {
|
|
Overlays.editOverlay(self.debugSpheres[sphereName], {
|
|
solid: isSolid
|
|
});
|
|
}
|
|
}
|
|
};
|
|
|
|
};
|
|
|
|
var SOCCER_WALK_SPEED = 5.0;
|
|
var initialWalkSpeed = MyAvatar.walkSpeed;
|
|
MyAvatar.walkSpeed = SOCCER_WALK_SPEED;
|
|
|
|
var PI = 3.14159;
|
|
var defaultRotation = {x: 0, y: 0, z: 0, w: 1};
|
|
var debugSphere1ID = "sphere1";
|
|
var debugSphere2ID = "sphere2";
|
|
var visualDebugger = new soccerDebug();
|
|
visualDebugger.setVisible(true);
|
|
//visualDebugger.setDebugSphere(debugSphere1ID, MyAvatar.position, 0.1);
|
|
//visualDebugger.setDebugSphere(debugSphere2ID, MyAvatar.position, 0.1);
|
|
var hipsOffset = 0.4;
|
|
var radius = 0.15;
|
|
|
|
var FEET_COLLIDER_PROPERTIES = {
|
|
type: "Sphere",
|
|
dimensions: { x: radius * 2, y: radius * 2, z: radius * 2},
|
|
position: { x: 0, y: 0, z: 0 },
|
|
gravity: { x: 0, y: 0, z: 0 },
|
|
density: 10000,
|
|
collidesWith: "dynamic",
|
|
visible: false,
|
|
collisionMask: 2,
|
|
dynamic: true
|
|
}
|
|
|
|
var FEET_FORWARD = 0.2;
|
|
|
|
var SoccerController = function() {
|
|
var _this = this;
|
|
this.lastLeftAlpha = 0.0;
|
|
this.lastRightAlpha = 0.0;
|
|
this.avatarData = new (function(){
|
|
var self = this;
|
|
|
|
this.advancedControls = MyAvatar.useAdvancedMovementControls
|
|
|
|
this.position = MyAvatar.position;
|
|
this.orientation = MyAvatar.orientation;
|
|
|
|
this.forward = Quat.getForward(MyAvatar.orientation);
|
|
this.right = Quat.getRight(MyAvatar.orientation);
|
|
this.up = Quat.getUp(MyAvatar.orientation);
|
|
|
|
this.leftFootIndex = MyAvatar.getJointIndex("LeftFoot");
|
|
this.rightFootIndex = MyAvatar.getJointIndex("RightFoot");
|
|
this.leftLegIndex = MyAvatar.getJointIndex("LeftUpLeg");
|
|
this.rightLegIndex = MyAvatar.getJointIndex("RightUpLeg");
|
|
this.leftHandIndex = MyAvatar.getJointIndex("LeftHand");
|
|
this.rightHandIndex = MyAvatar.getJointIndex("RightHand");
|
|
|
|
this.update = function(position, orientation) {
|
|
self.position = position;
|
|
self.orientation = orientation;
|
|
self.forward = Quat.getForward(self.orientation);
|
|
self.right = Quat.getRight(self.orientation);
|
|
self.up = Quat.getUp(self.orientation);
|
|
}
|
|
});
|
|
|
|
this.colliders = new (function(){
|
|
var self = this;
|
|
this.DELTA_MULTIPLIER = 30.0;
|
|
this.left = {
|
|
index: _this.avatarData.leftFootIndex,
|
|
entityID: Entities.addEntity(FEET_COLLIDER_PROPERTIES),
|
|
lastVelocity: Vec3.ZERO,
|
|
offset: 0
|
|
}
|
|
this.right = {
|
|
index: _this.avatarData.rightFootIndex,
|
|
entityID: Entities.addEntity(FEET_COLLIDER_PROPERTIES),
|
|
lastVelocity: Vec3.ZERO,
|
|
offset: 0
|
|
}
|
|
this.moveToPosition = function(side) {
|
|
var newPosition = Vec3.sum(MyAvatar.getJointPosition(side.index), Vec3.sum({x:0, y:side.offset, z:0}, Vec3.multiply(_this.avatarData.forward, FEET_FORWARD)));
|
|
var currentPosition = Entities.getEntityProperties(side.entityID, ["position"]).position;
|
|
var velocity = Vec3.multiply(Vec3.subtract(newPosition, currentPosition), self.DELTA_MULTIPLIER);
|
|
var acceleration = Vec3.multiply(Vec3.subtract(velocity, side.lastVelocity), self.DELTA_MULTIPLIER);
|
|
side.lastVelocity = velocity;
|
|
Entities.editEntity(side.entityID, { velocity: velocity, gravity: acceleration });
|
|
}
|
|
this.setOffset = function(handController, offset) {
|
|
var side = (handController === Controller.Standard.RightHand) ? self.right : self.left;
|
|
side.offset = offset;
|
|
}
|
|
this.update = function() {
|
|
self.moveToPosition(self.left);
|
|
self.moveToPosition(self.right);
|
|
}
|
|
this.cleanup = function() {
|
|
Entities.deleteEntity(self.left.entityID);
|
|
Entities.deleteEntity(self.right.entityID);
|
|
}
|
|
});
|
|
|
|
this.getControllerWorldLocation = function (handController) {
|
|
var orientation;
|
|
var position;
|
|
var pose = Controller.getPoseValue(handController);
|
|
var valid = pose.valid;
|
|
var controllerJointIndex;
|
|
if (pose.valid) {
|
|
if (handController === Controller.Standard.RightHand) {
|
|
controllerJointIndex = MyAvatar.getJointIndex("_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND");
|
|
} else {
|
|
controllerJointIndex = MyAvatar.getJointIndex("_CAMERA_RELATIVE_CONTROLLER_LEFTHAND");
|
|
}
|
|
orientation = Quat.multiply(MyAvatar.orientation, MyAvatar.getAbsoluteJointRotationInObjectFrame(controllerJointIndex));
|
|
position = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, MyAvatar.getAbsoluteJointTranslationInObjectFrame(controllerJointIndex)));
|
|
|
|
} else if (!HMD.isHandControllerAvailable()) {
|
|
// NOTE: keep this offset in sync with scripts/system/controllers/handControllerPointer.js:493
|
|
var VERTICAL_HEAD_LASER_OFFSET = 0.1;
|
|
position = Vec3.sum(Camera.position, Vec3.multiplyQbyV(Camera.orientation, {x: 0, y: VERTICAL_HEAD_LASER_OFFSET, z: 0}));
|
|
orientation = Quat.multiply(Camera.orientation, Quat.angleAxis(-90, { x: 1, y: 0, z: 0 }));
|
|
valid = true;
|
|
}
|
|
|
|
return {position: position,
|
|
translation: position,
|
|
orientation: orientation,
|
|
rotation: orientation,
|
|
valid: valid};
|
|
};
|
|
|
|
this.getControllerOffset = function(handController) {
|
|
var controllerPosition = handController === Controller.Standard.RightHand ? MyAvatar.getJointPosition(_this.avatarData.rightHandIndex) : MyAvatar.getJointPosition(_this.avatarData.leftHandIndex);// _this.getControllerWorldLocation(handController).position;
|
|
var rightMultiplier = (handController == Controller.Standard.RightHand) ? 0.5 : -0.5;
|
|
var referenceOffset = Vec3.sum(Vec3.multiply(_this.avatarData.forward, hipsOffset), Vec3.multiply(_this.avatarData.right, rightMultiplier * hipsOffset));
|
|
var hipOffset = Vec3.sum(_this.avatarData.position, {x: 0, y: 0.2, x: 0});
|
|
var referencePos = Vec3.sum(hipOffset, referenceOffset);
|
|
var controllerOffset = Vec3.subtract(controllerPosition, referencePos);
|
|
return controllerOffset;
|
|
};
|
|
|
|
this.updateAvatarData = function() {
|
|
_this.avatarData.update(MyAvatar.position, MyAvatar.orientation);
|
|
};
|
|
|
|
this.updateLeg = function(handController, alpha) {
|
|
if (alpha > 0) {
|
|
var controllerOffset = _this.getControllerOffset(handController);
|
|
var xAngle = Vec3.getAngle(controllerOffset, Vec3.sum(_this.avatarData.forward, Vec3.multiply(_this.avatarData.up, 0.5)));
|
|
var zAngle = Vec3.getAngle(controllerOffset, _this.avatarData.right);
|
|
var yAmount = Vec3.dot(Vec3.normalize(controllerOffset), _this.avatarData.up);
|
|
var yOffset = yAmount < 0 ? 0.5 * yAmount : 0;
|
|
_this.colliders.setOffset(handController, yOffset);
|
|
var rotation = Quat.fromVec3Radians({x:-1.5*xAngle, y:PI + -0.5 + 0.3*zAngle, z:0});
|
|
var jointIndex = (handController == Controller.Standard.RightHand) ? _this.avatarData.rightLegIndex : _this.avatarData.leftLegIndex;
|
|
MyAvatar.setJointRotation(jointIndex, Quat.slerp(MyAvatar.getJointRotation(jointIndex), rotation, alpha));
|
|
}
|
|
if (handController == Controller.Standard.RightHand) {
|
|
if (_this.lastRightAlpha > 0.0 && alpha == 0.0) {
|
|
MyAvatar.clearJointsData();
|
|
}
|
|
_this.lastRightAlpha = alpha;
|
|
} else {
|
|
if (_this.lastLeftAlpha > 0.0 && alpha == 0.0) {
|
|
MyAvatar.clearJointsData();
|
|
}
|
|
_this.lastLeftAlpha = alpha;
|
|
}
|
|
|
|
};
|
|
}
|
|
|
|
var soccerController = new SoccerController();
|
|
|
|
// Disable teleport
|
|
Messages.sendMessage("Hifi-Teleport-Disabler", "both");
|
|
|
|
Script.update.connect(function(){
|
|
|
|
soccerController.updateAvatarData();
|
|
soccerController.updateLeg(Controller.Standard.LeftHand, Controller.getValue(Controller.Standard.LeftGrip));
|
|
soccerController.updateLeg(Controller.Standard.RightHand, Controller.getValue(Controller.Standard.RightGrip));
|
|
soccerController.colliders.update();
|
|
|
|
});
|
|
Script.scriptEnding.connect(function() {
|
|
Messages.sendMessage("Hifi-Teleport-Disabler", "none");
|
|
soccerController.colliders.cleanup();
|
|
visualDebugger.cleanup();
|
|
});
|
|
})(); |