Merge pull request #2952 from Atlante45/click_drag_attach

Click drag attach!
This commit is contained in:
Andrzej Kapolka 2014-05-29 18:55:33 -07:00
commit f42199b3e1
6 changed files with 136 additions and 19 deletions

View file

@ -40,6 +40,8 @@ var modelURLs = [
var toolBar;
var jointList = MyAvatar.getJointNames();
function isLocked(properties) {
// special case to lock the ground plane model in hq.
if (location.hostname == "hq.highfidelity.io" &&
@ -81,10 +83,13 @@ function controller(wichSide) {
this.grabbing = false;
this.modelID = { isKnownID: false };
this.modelURL = "";
this.oldModelRotation;
this.oldModelPosition;
this.oldModelRadius;
this.jointsIntersectingFromStart = [];
this.laser = Overlays.addOverlay("line3d", {
position: { x: 0, y: 0, z: 0 },
end: { x: 0, y: 0, z: 0 },
@ -134,16 +139,65 @@ function controller(wichSide) {
this.grabbing = true;
this.modelID = modelID;
this.modelURL = properties.modelURL;
this.oldModelPosition = properties.position;
this.oldModelRotation = properties.modelRotation;
this.oldModelRadius = properties.radius;
this.jointsIntersectingFromStart = [];
for (var i = 0; i < jointList.length; i++) {
var distance = Vec3.distance(MyAvatar.getJointPosition(jointList[i]), this.oldModelPosition);
if (distance < this.oldModelRadius) {
this.jointsIntersectingFromStart.push(i);
}
}
}
}
this.release = function () {
if (this.grabbing) {
if (jointList.length <= 0) {
jointList = MyAvatar.getJointNames();
}
var closestJointIndex = -1;
var closestJointDistance = 10;
for (var i = 0; i < jointList.length; i++) {
var distance = Vec3.distance(MyAvatar.getJointPosition(jointList[i]), this.oldModelPosition);
if (distance < closestJointDistance) {
closestJointDistance = distance;
closestJointIndex = i;
}
}
print("closestJoint: " + jointList[closestJointIndex]);
print("closestJointDistance (attach max distance): " + closestJointDistance + " (" + this.oldModelRadius + ")");
if (closestJointDistance < this.oldModelRadius) {
if (this.jointsIntersectingFromStart.indexOf(closestJointIndex) != -1) {
// Do nothing
} else {
print("Attaching to " + jointList[closestJointIndex]);
var jointPosition = MyAvatar.getJointPosition(jointList[closestJointIndex]);
var jointRotation = MyAvatar.getJointCombinedRotation(jointList[closestJointIndex]);
var attachmentOffset = Vec3.subtract(this.oldModelPosition, jointPosition);
attachmentOffset = Vec3.multiplyQbyV(Quat.inverse(jointRotation), attachmentOffset);
var attachmentRotation = Quat.multiply(Quat.inverse(jointRotation), this.oldModelRotation);
MyAvatar.attach(this.modelURL, jointList[closestJointIndex],
attachmentOffset, attachmentRotation, 2.0 * this.oldModelRadius,
true, false);
Models.deleteModel(this.modelID);
}
}
}
this.grabbing = false;
this.modelID.isKnownID = false;
this.jointsIntersectingFromStart = [];
}
this.checkTrigger = function () {
@ -251,11 +305,6 @@ function controller(wichSide) {
position: newPosition,
modelRotation: newRotation
});
// print("Moving " + this.modelID.id);
// Vec3.print("Old Position: ", this.oldModelPosition);
// Vec3.print("Sav Position: ", newPosition);
// Quat.print("Old Rotation: ", this.oldModelRotation);
// Quat.print("New Rotation: ", newRotation);
this.oldModelRotation = newRotation;
this.oldModelPosition = newPosition;
@ -410,8 +459,6 @@ function checkController(deltaTime) {
moveOverlays();
}
function initToolBar() {
toolBar = new ToolBar(0, 0, ToolBar.VERTICAL);
// New Model

View file

@ -28,8 +28,10 @@ var NEW_VOXEL_SIZE = 1.0;
var NEW_VOXEL_DISTANCE_FROM_CAMERA = 3.0;
var PIXELS_PER_EXTRUDE_VOXEL = 16;
var WHEEL_PIXELS_PER_SCALE_CHANGE = 100;
var MAX_VOXEL_SCALE = 16.0;
var MIN_VOXEL_SCALE = 1.0 / Math.pow(2.0, 8.0);
var MAX_VOXEL_SCALE_POWER = 4;
var MIN_VOXEL_SCALE_POWER = -8;
var MAX_VOXEL_SCALE = Math.pow(2.0, MAX_VOXEL_SCALE_POWER);
var MIN_VOXEL_SCALE = Math.pow(2.0, MIN_VOXEL_SCALE_POWER);
var WHITE_COLOR = { red: 255, green: 255, blue: 255 };
var MAX_PASTE_VOXEL_SCALE = 256;
@ -330,6 +332,13 @@ function ScaleSelector() {
visible: false
});
this.setScale = function(scale) {
if (scale > MAX_VOXEL_SCALE) {
scale = MAX_VOXEL_SCALE;
}
if (scale < MIN_VOXEL_SCALE) {
scale = MIN_VOXEL_SCALE;
}
this.scale = scale;
this.power = Math.floor(Math.log(scale) / Math.log(2));
rescaleImport();
@ -391,12 +400,9 @@ function ScaleSelector() {
this.incrementScale = function() {
copyScale = false;
if (this.power < 13) {
if (this.power < MAX_VOXEL_SCALE_POWER) {
++this.power;
this.scale *= 2.0;
if (this.scale > MAX_VOXEL_SCALE) {
this.scale = MAX_VOXEL_SCALE;
}
this.update();
rescaleImport();
resizeVoxelSound.play(voxelSizePlus);
@ -405,7 +411,7 @@ function ScaleSelector() {
this.decrementScale = function() {
copyScale = false;
if (-4 < this.power) {
if (MIN_VOXEL_SCALE_POWER < this.power) {
--this.power;
this.scale /= 2.0;
this.update();

View file

@ -378,10 +378,10 @@ void Avatar::simulateAttachments(float deltaTime) {
model->setLODDistance(getLODDistance());
}
if (_skeletonModel.getJointPosition(jointIndex, jointPosition) &&
_skeletonModel.getJointRotation(jointIndex, jointRotation)) {
_skeletonModel.getJointCombinedRotation(jointIndex, jointRotation)) {
model->setTranslation(jointPosition + jointRotation * attachment.translation * _scale);
model->setRotation(jointRotation * attachment.rotation);
model->setScale(_skeletonModel.getScale() * attachment.scale);
model->setScaleToFit(true, _scale * attachment.scale);
model->simulate(deltaTime);
}
}
@ -705,6 +705,54 @@ QStringList Avatar::getJointNames() const {
return _skeletonModel.isActive() ? _skeletonModel.getGeometry()->getFBXGeometry().getJointNames() : QStringList();
}
glm::vec3 Avatar::getJointPosition(int index) const {
if (QThread::currentThread() != thread()) {
glm::vec3 position;
QMetaObject::invokeMethod(const_cast<Avatar*>(this), "getJointPosition", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(glm::vec3, position), Q_ARG(const int, index));
return position;
}
glm::vec3 position;
_skeletonModel.getJointPosition(index, position);
return position;
}
glm::vec3 Avatar::getJointPosition(const QString& name) const {
if (QThread::currentThread() != thread()) {
glm::vec3 position;
QMetaObject::invokeMethod(const_cast<Avatar*>(this), "getJointPosition", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(glm::vec3, position), Q_ARG(const QString&, name));
return position;
}
glm::vec3 position;
_skeletonModel.getJointPosition(getJointIndex(name), position);
return position;
}
glm::quat Avatar::getJointCombinedRotation(int index) const {
if (QThread::currentThread() != thread()) {
glm::quat rotation;
QMetaObject::invokeMethod(const_cast<Avatar*>(this), "getJointCombinedRotation", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(glm::quat, rotation), Q_ARG(const int, index));
return rotation;
}
glm::quat rotation;
_skeletonModel.getJointCombinedRotation(index, rotation);
return rotation;
}
glm::quat Avatar::getJointCombinedRotation(const QString& name) const {
if (QThread::currentThread() != thread()) {
glm::quat rotation;
QMetaObject::invokeMethod(const_cast<Avatar*>(this), "getJointCombinedRotation", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(glm::quat, rotation), Q_ARG(const QString&, name));
return rotation;
}
glm::quat rotation;
_skeletonModel.getJointCombinedRotation(getJointIndex(name), rotation);
return rotation;
}
void Avatar::setFaceModelURL(const QUrl& faceModelURL) {
AvatarData::setFaceModelURL(faceModelURL);
const QUrl DEFAULT_FACE_MODEL_URL = QUrl::fromLocalFile(Application::resourcesPath() + "meshes/defaultAvatar_head.fst");
@ -734,6 +782,8 @@ void Avatar::setAttachmentData(const QVector<AttachmentData>& attachmentData) {
// update the urls
for (int i = 0; i < attachmentData.size(); i++) {
_attachmentModels[i]->setSnapModelToCenter(true);
_attachmentModels[i]->setScaleToFit(true, _scale * _attachmentData.at(i).scale);
_attachmentModels[i]->setURL(attachmentData.at(i).modelURL);
}
}

View file

@ -152,7 +152,12 @@ public:
quint32 getCollisionGroups() const { return _collisionGroups; }
virtual void setCollisionGroups(quint32 collisionGroups) { _collisionGroups = (collisionGroups & VALID_COLLISION_GROUPS); }
Q_INVOKABLE glm::vec3 getJointPosition(int index) const;
Q_INVOKABLE glm::vec3 getJointPosition(const QString& name) const;
Q_INVOKABLE glm::quat getJointCombinedRotation(int index) const;
Q_INVOKABLE glm::quat getJointCombinedRotation(const QString& name) const;
public slots:
void updateCollisionGroups();

View file

@ -634,8 +634,16 @@ bool Model::getJointRotation(int jointIndex, glm::quat& rotation, bool fromBind)
return false;
}
rotation = _jointStates[jointIndex]._combinedRotation *
(fromBind ? _geometry->getFBXGeometry().joints[jointIndex].inverseBindRotation :
_geometry->getFBXGeometry().joints[jointIndex].inverseDefaultRotation);
(fromBind ? _geometry->getFBXGeometry().joints[jointIndex].inverseBindRotation :
_geometry->getFBXGeometry().joints[jointIndex].inverseDefaultRotation);
return true;
}
bool Model::getJointCombinedRotation(int jointIndex, glm::quat& rotation) const {
if (jointIndex == -1 || _jointStates.isEmpty()) {
return false;
}
rotation = _jointStates[jointIndex]._combinedRotation;
return true;
}

View file

@ -144,6 +144,7 @@ public:
bool getJointPosition(int jointIndex, glm::vec3& position) const;
bool getJointRotation(int jointIndex, glm::quat& rotation, bool fromBind = false) const;
bool getJointCombinedRotation(int jointIndex, glm::quat& rotation) const;
QStringList getJointNames() const;