mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-08-04 15:05:37 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into objReader
This commit is contained in:
commit
ee93e1d300
15 changed files with 275 additions and 115 deletions
|
@ -50,6 +50,9 @@ var dropLine = Overlays.addOverlay("line3d", {
|
|||
|
||||
|
||||
function mousePressEvent(event) {
|
||||
if(!event.isLeftButton){
|
||||
return;
|
||||
}
|
||||
var pickRay = Camera.computePickRay(event.x, event.y);
|
||||
var intersection = Entities.findRayIntersection(pickRay);
|
||||
if (intersection.intersects && intersection.properties.collisionsWillMove) {
|
||||
|
@ -83,7 +86,7 @@ function mousePressEvent(event) {
|
|||
|
||||
function mouseReleaseEvent() {
|
||||
if (isGrabbing) {
|
||||
flingObject();
|
||||
// flingObject();
|
||||
Entities.editEntity(grabbedEntity, {
|
||||
gravity: savedGravity
|
||||
});
|
||||
|
@ -100,7 +103,6 @@ function flingObject() {
|
|||
|
||||
flingVelocity = Vec3.subtract(entityProps.position, prevPosition);
|
||||
flingVelocity = Vec3.multiply(flingMultiplier, flingVelocity);
|
||||
flingVelocity.y = 0;
|
||||
Entities.editEntity(grabbedEntity, {
|
||||
velocity: flingVelocity
|
||||
});
|
||||
|
@ -109,7 +111,6 @@ function flingObject() {
|
|||
function mouseMoveEvent(event) {
|
||||
if (isGrabbing) {
|
||||
entityProps = Entities.getEntityProperties(grabbedEntity);
|
||||
prevPosition = entityProps.position;
|
||||
avatarEntityDistance = Vec3.distance(MyAvatar.position, entityProps.position);
|
||||
finalMoveMultiplier = baseMoveFactor * Math.pow(avatarEntityDistance, 1.5);
|
||||
deltaMouse.x = event.x - prevMouse.x;
|
||||
|
@ -134,9 +135,17 @@ function mouseMoveEvent(event) {
|
|||
z: 0
|
||||
})
|
||||
});
|
||||
|
||||
flingVelocity = Vec3.subtract(entityProps.position, prevPosition);
|
||||
flingVelocity = Vec3.multiply(flingMultiplier, flingVelocity);
|
||||
Entities.editEntity(grabbedEntity, {
|
||||
velocity: flingVelocity
|
||||
});
|
||||
prevPosition = entityProps.position;
|
||||
}
|
||||
prevMouse.x = event.x;
|
||||
prevMouse.y = event.y;
|
||||
|
||||
}
|
||||
|
||||
function keyReleaseEvent(event) {
|
||||
|
@ -151,11 +160,6 @@ function keyPressEvent(event) {
|
|||
}
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
Entities.deleteEntity(box);
|
||||
Entities.deleteEntity(box2);
|
||||
Entities.deleteEntity(ground);
|
||||
}
|
||||
|
||||
function setUpTestObjects() {
|
||||
var distance = 4;
|
||||
|
@ -226,4 +230,3 @@ Controller.mousePressEvent.connect(mousePressEvent);
|
|||
Controller.mouseReleaseEvent.connect(mouseReleaseEvent);
|
||||
Controller.keyPressEvent.connect(keyPressEvent);
|
||||
Controller.keyReleaseEvent.connect(keyReleaseEvent);
|
||||
Script.scriptEnding.connect(cleanup);
|
|
@ -66,7 +66,7 @@ DialogBase {
|
|||
|
||||
// our close function performs the same way as the OffscreenUI class:
|
||||
// don't do anything but manipulate the enabled flag and let the other
|
||||
// mechanisms decide if the window should be destoryed after the close
|
||||
// mechanisms decide if the window should be destroyed after the close
|
||||
// animation completes
|
||||
function close() {
|
||||
if (destroyOnCloseButton) {
|
||||
|
|
|
@ -65,16 +65,16 @@ static const int DDE_TO_FACESHIFT_MAPPING[] = {
|
|||
// The DDE coefficients, overall, range from -0.2 to 1.5 or so. However, individual coefficients typically vary much
|
||||
// less than this.
|
||||
static const float DDE_COEFFICIENT_SCALES[] = {
|
||||
4.0f, // EyeBlink_L
|
||||
4.0f, // EyeBlink_R
|
||||
1.0f, // EyeBlink_L
|
||||
1.0f, // EyeBlink_R
|
||||
1.0f, // EyeSquint_L
|
||||
1.0f, // EyeSquint_R
|
||||
1.0f, // EyeDown_L
|
||||
1.0f, // EyeDown_R
|
||||
1.0f, // EyeIn_L
|
||||
1.0f, // EyeIn_R
|
||||
4.0f, // EyeOpen_L
|
||||
4.0f, // EyeOpen_R
|
||||
1.0f, // EyeOpen_L
|
||||
1.0f, // EyeOpen_R
|
||||
1.0f, // EyeOut_L
|
||||
1.0f, // EyeOut_R
|
||||
1.0f, // EyeUp_L
|
||||
|
@ -136,6 +136,16 @@ struct Packet {
|
|||
|
||||
const float STARTING_DDE_MESSAGE_TIME = 0.033f;
|
||||
|
||||
const int FPS_TIMER_DELAY = 2000; // ms
|
||||
const int FPS_TIMER_DURATION = 2000; // ms
|
||||
|
||||
#ifdef WIN32
|
||||
// warning C4351: new behavior: elements of array 'DdeFaceTracker::_lastEyeBlinks' will be default initialized
|
||||
// warning C4351: new behavior: elements of array 'DdeFaceTracker::_filteredEyeBlinks' will be default initialized
|
||||
// warning C4351: new behavior: elements of array 'DdeFaceTracker::_lastEyeCoefficients' will be default initialized
|
||||
#pragma warning(disable:4351)
|
||||
#endif
|
||||
|
||||
DdeFaceTracker::DdeFaceTracker() :
|
||||
DdeFaceTracker(QHostAddress::Any, DDE_SERVER_PORT, DDE_CONTROL_PORT)
|
||||
{
|
||||
|
@ -166,24 +176,35 @@ DdeFaceTracker::DdeFaceTracker(const QHostAddress& host, quint16 serverPort, qui
|
|||
_averageMessageTime(STARTING_DDE_MESSAGE_TIME),
|
||||
_lastHeadTranslation(glm::vec3(0.0f)),
|
||||
_filteredHeadTranslation(glm::vec3(0.0f)),
|
||||
_lastLeftEyeBlink(0.0f),
|
||||
_filteredLeftEyeBlink(0.0f),
|
||||
_lastRightEyeBlink(0.0f),
|
||||
_filteredRightEyeBlink(0.0f)
|
||||
_lastBrowUp(0.0f),
|
||||
_filteredBrowUp(0.0f),
|
||||
_lastEyeBlinks(),
|
||||
_filteredEyeBlinks(),
|
||||
_lastEyeCoefficients(),
|
||||
_isCalculatingFPS(false),
|
||||
_frameCount(0)
|
||||
{
|
||||
_coefficients.resize(NUM_FACESHIFT_BLENDSHAPES);
|
||||
|
||||
_blendshapeCoefficients.resize(NUM_FACESHIFT_BLENDSHAPES);
|
||||
|
||||
|
||||
_eyeStates[0] = EYE_OPEN;
|
||||
_eyeStates[1] = EYE_OPEN;
|
||||
|
||||
connect(&_udpSocket, SIGNAL(readyRead()), SLOT(readPendingDatagrams()));
|
||||
connect(&_udpSocket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(socketErrorOccurred(QAbstractSocket::SocketError)));
|
||||
connect(&_udpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), SLOT(socketStateChanged(QAbstractSocket::SocketState)));
|
||||
connect(&_udpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
|
||||
SLOT(socketStateChanged(QAbstractSocket::SocketState)));
|
||||
}
|
||||
|
||||
DdeFaceTracker::~DdeFaceTracker() {
|
||||
setEnabled(false);
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning(default:4351)
|
||||
#endif
|
||||
|
||||
void DdeFaceTracker::setEnabled(bool enabled) {
|
||||
#ifdef HAVE_DDE
|
||||
// isOpen() does not work as one might expect on QUdpSocket; don't test isOpen() before closing socket.
|
||||
|
@ -350,49 +371,25 @@ void DdeFaceTracker::decodePacket(const QByteArray& buffer) {
|
|||
}
|
||||
|
||||
// Translate DDE coefficients to Faceshift compatible coefficients
|
||||
for (int i = 0; i < NUM_EXPRESSIONS; i += 1) {
|
||||
for (int i = 0; i < NUM_EXPRESSIONS; i++) {
|
||||
_coefficients[DDE_TO_FACESHIFT_MAPPING[i]] = packet.expressions[i];
|
||||
}
|
||||
|
||||
// Use EyeBlink values to control both EyeBlink and EyeOpen
|
||||
static const float RELAXED_EYE_VALUE = 0.1f;
|
||||
float leftEye = _coefficients[_leftBlinkIndex];
|
||||
float rightEye = _coefficients[_rightBlinkIndex];
|
||||
if (isFiltering) {
|
||||
const float BLINK_VELOCITY_FILTER_STRENGTH = 0.3f;
|
||||
|
||||
float velocity = fabs(leftEye - _lastLeftEyeBlink) / _averageMessageTime;
|
||||
float velocityFilter = glm::clamp(velocity * BLINK_VELOCITY_FILTER_STRENGTH, 0.0f, 1.0f);
|
||||
_filteredLeftEyeBlink = velocityFilter * leftEye + (1.0f - velocityFilter) * _filteredLeftEyeBlink;
|
||||
_lastLeftEyeBlink = leftEye;
|
||||
leftEye = _filteredLeftEyeBlink;
|
||||
|
||||
velocity = fabs(rightEye - _lastRightEyeBlink) / _averageMessageTime;
|
||||
velocityFilter = glm::clamp(velocity * BLINK_VELOCITY_FILTER_STRENGTH, 0.0f, 1.0f);
|
||||
_filteredRightEyeBlink = velocityFilter * rightEye + (1.0f - velocityFilter) * _filteredRightEyeBlink;
|
||||
_lastRightEyeBlink = rightEye;
|
||||
rightEye = _filteredRightEyeBlink;
|
||||
}
|
||||
if (leftEye > RELAXED_EYE_VALUE) {
|
||||
_coefficients[_leftBlinkIndex] = leftEye - RELAXED_EYE_VALUE;
|
||||
_coefficients[_leftEyeOpenIndex] = 0.0f;
|
||||
} else {
|
||||
_coefficients[_leftBlinkIndex] = 0.0f;
|
||||
_coefficients[_leftEyeOpenIndex] = RELAXED_EYE_VALUE - leftEye;
|
||||
}
|
||||
if (rightEye > RELAXED_EYE_VALUE) {
|
||||
_coefficients[_rightBlinkIndex] = rightEye - RELAXED_EYE_VALUE;
|
||||
_coefficients[_rightEyeOpenIndex] = 0.0f;
|
||||
} else {
|
||||
_coefficients[_rightBlinkIndex] = 0.0f;
|
||||
_coefficients[_rightEyeOpenIndex] = RELAXED_EYE_VALUE - rightEye;
|
||||
}
|
||||
|
||||
// Use BrowsU_C to control both brows' up and down
|
||||
_coefficients[_browDownLeftIndex] = -_coefficients[_browUpCenterIndex];
|
||||
_coefficients[_browDownRightIndex] = -_coefficients[_browUpCenterIndex];
|
||||
_coefficients[_browUpLeftIndex] = _coefficients[_browUpCenterIndex];
|
||||
_coefficients[_browUpRightIndex] = _coefficients[_browUpCenterIndex];
|
||||
float browUp = _coefficients[_browUpCenterIndex];
|
||||
if (isFiltering) {
|
||||
const float BROW_VELOCITY_FILTER_STRENGTH = 0.75f;
|
||||
float velocity = fabs(browUp - _lastBrowUp) / _averageMessageTime;
|
||||
float velocityFilter = glm::clamp(velocity * BROW_VELOCITY_FILTER_STRENGTH, 0.0f, 1.0f);
|
||||
_filteredBrowUp = velocityFilter * browUp + (1.0f - velocityFilter) * _filteredBrowUp;
|
||||
_lastBrowUp = browUp;
|
||||
browUp = _filteredBrowUp;
|
||||
_coefficients[_browUpCenterIndex] = browUp;
|
||||
}
|
||||
_coefficients[_browUpLeftIndex] = browUp;
|
||||
_coefficients[_browUpRightIndex] = browUp;
|
||||
_coefficients[_browDownLeftIndex] = -browUp;
|
||||
_coefficients[_browDownRightIndex] = -browUp;
|
||||
|
||||
// Offset jaw open coefficient
|
||||
static const float JAW_OPEN_THRESHOLD = 0.16f;
|
||||
|
@ -403,9 +400,91 @@ void DdeFaceTracker::decodePacket(const QByteArray& buffer) {
|
|||
_coefficients[_mouthSmileLeftIndex] = _coefficients[_mouthSmileLeftIndex] - SMILE_THRESHOLD;
|
||||
_coefficients[_mouthSmileRightIndex] = _coefficients[_mouthSmileRightIndex] - SMILE_THRESHOLD;
|
||||
|
||||
// Velocity filter EyeBlink values
|
||||
const float DDE_EYEBLINK_SCALE = 3.0f;
|
||||
float eyeBlinks[] = { DDE_EYEBLINK_SCALE * _coefficients[_leftBlinkIndex], DDE_EYEBLINK_SCALE * _coefficients[_rightBlinkIndex] };
|
||||
if (isFiltering) {
|
||||
const float BLINK_VELOCITY_FILTER_STRENGTH = 0.3f;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
float velocity = fabs(eyeBlinks[i] - _lastEyeBlinks[i]) / _averageMessageTime;
|
||||
float velocityFilter = glm::clamp(velocity * BLINK_VELOCITY_FILTER_STRENGTH, 0.0f, 1.0f);
|
||||
_filteredEyeBlinks[i] = velocityFilter * eyeBlinks[i] + (1.0f - velocityFilter) * _filteredEyeBlinks[i];
|
||||
_lastEyeBlinks[i] = eyeBlinks[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Finesse EyeBlink values
|
||||
float eyeCoefficients[2];
|
||||
for (int i = 0; i < 2; i++) {
|
||||
// Scale EyeBlink values so that they can be used to control both EyeBlink and EyeOpen
|
||||
// -ve values control EyeOpen; +ve values control EyeBlink
|
||||
static const float EYE_CONTROL_THRESHOLD = 0.5f; // Resting eye value
|
||||
eyeCoefficients[i] = (_filteredEyeBlinks[i] - EYE_CONTROL_THRESHOLD) / (1.0f - EYE_CONTROL_THRESHOLD);
|
||||
|
||||
// Change to closing or opening states
|
||||
const float EYE_CONTROL_HYSTERISIS = 0.25f;
|
||||
const float EYE_CLOSING_THRESHOLD = 0.95f;
|
||||
const float EYE_OPENING_THRESHOLD = EYE_CONTROL_THRESHOLD - EYE_CONTROL_HYSTERISIS;
|
||||
if ((_eyeStates[i] == EYE_OPEN || _eyeStates[i] == EYE_OPENING) && eyeCoefficients[i] > EYE_CLOSING_THRESHOLD) {
|
||||
_eyeStates[i] = EYE_CLOSING;
|
||||
} else if ((_eyeStates[i] == EYE_CLOSED || _eyeStates[i] == EYE_CLOSING)
|
||||
&& eyeCoefficients[i] < EYE_OPENING_THRESHOLD) {
|
||||
_eyeStates[i] = EYE_OPENING;
|
||||
}
|
||||
|
||||
const float EYELID_MOVEMENT_RATE = 10.0f; // units/second
|
||||
const float EYE_OPEN_SCALE = 0.2f;
|
||||
if (_eyeStates[i] == EYE_CLOSING) {
|
||||
// Close eyelid until it's fully closed
|
||||
float closingValue = _lastEyeCoefficients[i] + EYELID_MOVEMENT_RATE * _averageMessageTime;
|
||||
if (closingValue >= 1.0) {
|
||||
_eyeStates[i] = EYE_CLOSED;
|
||||
eyeCoefficients[i] = 1.0;
|
||||
} else {
|
||||
eyeCoefficients[i] = closingValue;
|
||||
}
|
||||
} else if (_eyeStates[i] == EYE_OPENING) {
|
||||
// Open eyelid until it meets the current adjusted value
|
||||
float openingValue = _lastEyeCoefficients[i] - EYELID_MOVEMENT_RATE * _averageMessageTime;
|
||||
if (openingValue < eyeCoefficients[i] * EYE_OPEN_SCALE) {
|
||||
_eyeStates[i] = EYE_OPEN;
|
||||
eyeCoefficients[i] = eyeCoefficients[i] * EYE_OPEN_SCALE;
|
||||
} else {
|
||||
eyeCoefficients[i] = openingValue;
|
||||
}
|
||||
} else if (_eyeStates[i] == EYE_OPEN) {
|
||||
// Reduce eyelid movement
|
||||
eyeCoefficients[i] = eyeCoefficients[i] * EYE_OPEN_SCALE;
|
||||
} else if (_eyeStates[i] == EYE_CLOSED) {
|
||||
// Keep eyelid fully closed
|
||||
eyeCoefficients[i] = 1.0;
|
||||
}
|
||||
}
|
||||
if (_eyeStates[0] == EYE_OPEN && _eyeStates[1] == EYE_OPEN) {
|
||||
// Couple eyelids
|
||||
eyeCoefficients[0] = eyeCoefficients[1] = (eyeCoefficients[0] + eyeCoefficients[0]) / 2.0f;
|
||||
}
|
||||
_lastEyeCoefficients[0] = eyeCoefficients[0];
|
||||
_lastEyeCoefficients[1] = eyeCoefficients[1];
|
||||
|
||||
// Use EyeBlink values to control both EyeBlink and EyeOpen
|
||||
if (eyeCoefficients[0] > 0) {
|
||||
_coefficients[_leftBlinkIndex] = eyeCoefficients[0];
|
||||
_coefficients[_leftEyeOpenIndex] = 0.0f;
|
||||
} else {
|
||||
_coefficients[_leftBlinkIndex] = 0.0f;
|
||||
_coefficients[_leftEyeOpenIndex] = -eyeCoefficients[0];
|
||||
}
|
||||
if (eyeCoefficients[1] > 0) {
|
||||
_coefficients[_rightBlinkIndex] = eyeCoefficients[1];
|
||||
_coefficients[_rightEyeOpenIndex] = 0.0f;
|
||||
} else {
|
||||
_coefficients[_rightBlinkIndex] = 0.0f;
|
||||
_coefficients[_rightEyeOpenIndex] = -eyeCoefficients[1];
|
||||
}
|
||||
|
||||
// Scale all coefficients
|
||||
for (int i = 0; i < NUM_EXPRESSIONS; i += 1) {
|
||||
for (int i = 0; i < NUM_EXPRESSIONS; i++) {
|
||||
_blendshapeCoefficients[i]
|
||||
= glm::clamp(DDE_COEFFICIENT_SCALES[i] * _coefficients[i], 0.0f, 1.0f);
|
||||
}
|
||||
|
|
|
@ -103,12 +103,26 @@ private:
|
|||
|
||||
quint64 _lastMessageReceived;
|
||||
float _averageMessageTime;
|
||||
|
||||
glm::vec3 _lastHeadTranslation;
|
||||
glm::vec3 _filteredHeadTranslation;
|
||||
float _lastLeftEyeBlink;
|
||||
float _filteredLeftEyeBlink;
|
||||
float _lastRightEyeBlink;
|
||||
float _filteredRightEyeBlink;
|
||||
|
||||
float _lastBrowUp;
|
||||
float _filteredBrowUp;
|
||||
|
||||
enum EyeState {
|
||||
EYE_OPEN,
|
||||
EYE_CLOSING,
|
||||
EYE_CLOSED,
|
||||
EYE_OPENING
|
||||
};
|
||||
EyeState _eyeStates[2];
|
||||
float _lastEyeBlinks[2];
|
||||
float _filteredEyeBlinks[2];
|
||||
float _lastEyeCoefficients[2];
|
||||
|
||||
bool _isCalculatingFPS;
|
||||
int _frameCount;
|
||||
};
|
||||
|
||||
#endif // hifi_DdeFaceTracker_h
|
||||
#endif // hifi_DdeFaceTracker_h
|
||||
|
|
|
@ -295,20 +295,23 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|||
return changedProperties;
|
||||
}
|
||||
|
||||
QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine) const {
|
||||
QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool skipDefaults) const {
|
||||
QScriptValue properties = engine->newObject();
|
||||
EntityItemProperties defaultEntityProperties;
|
||||
|
||||
if (_idSet) {
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(id, _id.toString());
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(isKnownID, (_id != UNKNOWN_ENTITY_ID));
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(isKnownID, (_id != UNKNOWN_ENTITY_ID));
|
||||
} else {
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(isKnownID, false);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(isKnownID, false);
|
||||
}
|
||||
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(type, EntityTypes::getEntityTypeName(_type));
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_VEC3(position);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_VEC3(dimensions);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_VEC3(naturalDimensions); // gettable, but not settable
|
||||
if (!skipDefaults) {
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_VEC3(naturalDimensions); // gettable, but not settable
|
||||
}
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_QUAT(rotation);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_VEC3(velocity);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_VEC3(gravity);
|
||||
|
@ -316,8 +319,10 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine) cons
|
|||
COPY_PROPERTY_TO_QSCRIPTVALUE(damping);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(density);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(lifetime);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(age, getAge()); // gettable, but not settable
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(ageAsText, formatSecondsElapsed(getAge())); // gettable, but not settable
|
||||
if (!skipDefaults) {
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(age, getAge()); // gettable, but not settable
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(ageAsText, formatSecondsElapsed(getAge())); // gettable, but not settable
|
||||
}
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(script);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_VEC3(registrationPoint);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_VEC3(angularVelocity);
|
||||
|
@ -369,31 +374,37 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine) cons
|
|||
COPY_PROPERTY_TO_QSCRIPTVALUE(stageHour);
|
||||
|
||||
// Sitting properties support
|
||||
QScriptValue sittingPoints = engine->newObject();
|
||||
for (int i = 0; i < _sittingPoints.size(); ++i) {
|
||||
QScriptValue sittingPoint = engine->newObject();
|
||||
sittingPoint.setProperty("name", _sittingPoints.at(i).name);
|
||||
sittingPoint.setProperty("position", vec3toScriptValue(engine, _sittingPoints.at(i).position));
|
||||
sittingPoint.setProperty("rotation", quatToScriptValue(engine, _sittingPoints.at(i).rotation));
|
||||
sittingPoints.setProperty(i, sittingPoint);
|
||||
if (!skipDefaults) {
|
||||
QScriptValue sittingPoints = engine->newObject();
|
||||
for (int i = 0; i < _sittingPoints.size(); ++i) {
|
||||
QScriptValue sittingPoint = engine->newObject();
|
||||
sittingPoint.setProperty("name", _sittingPoints.at(i).name);
|
||||
sittingPoint.setProperty("position", vec3toScriptValue(engine, _sittingPoints.at(i).position));
|
||||
sittingPoint.setProperty("rotation", quatToScriptValue(engine, _sittingPoints.at(i).rotation));
|
||||
sittingPoints.setProperty(i, sittingPoint);
|
||||
}
|
||||
sittingPoints.setProperty("length", _sittingPoints.size());
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(sittingPoints, sittingPoints); // gettable, but not settable
|
||||
}
|
||||
sittingPoints.setProperty("length", _sittingPoints.size());
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(sittingPoints, sittingPoints); // gettable, but not settable
|
||||
|
||||
AABox aaBox = getAABox();
|
||||
QScriptValue boundingBox = engine->newObject();
|
||||
QScriptValue bottomRightNear = vec3toScriptValue(engine, aaBox.getCorner());
|
||||
QScriptValue topFarLeft = vec3toScriptValue(engine, aaBox.calcTopFarLeft());
|
||||
QScriptValue center = vec3toScriptValue(engine, aaBox.calcCenter());
|
||||
QScriptValue boundingBoxDimensions = vec3toScriptValue(engine, aaBox.getDimensions());
|
||||
boundingBox.setProperty("brn", bottomRightNear);
|
||||
boundingBox.setProperty("tfl", topFarLeft);
|
||||
boundingBox.setProperty("center", center);
|
||||
boundingBox.setProperty("dimensions", boundingBoxDimensions);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(boundingBox, boundingBox); // gettable, but not settable
|
||||
if (!skipDefaults) {
|
||||
AABox aaBox = getAABox();
|
||||
QScriptValue boundingBox = engine->newObject();
|
||||
QScriptValue bottomRightNear = vec3toScriptValue(engine, aaBox.getCorner());
|
||||
QScriptValue topFarLeft = vec3toScriptValue(engine, aaBox.calcTopFarLeft());
|
||||
QScriptValue center = vec3toScriptValue(engine, aaBox.calcCenter());
|
||||
QScriptValue boundingBoxDimensions = vec3toScriptValue(engine, aaBox.getDimensions());
|
||||
boundingBox.setProperty("brn", bottomRightNear);
|
||||
boundingBox.setProperty("tfl", topFarLeft);
|
||||
boundingBox.setProperty("center", center);
|
||||
boundingBox.setProperty("dimensions", boundingBoxDimensions);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(boundingBox, boundingBox); // gettable, but not settable
|
||||
}
|
||||
|
||||
QString textureNamesList = _textureNames.join(",\n");
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(originalTextures, textureNamesList); // gettable, but not settable
|
||||
if (!skipDefaults) {
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(originalTextures, textureNamesList); // gettable, but not settable
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
@ -467,7 +478,11 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object) {
|
|||
}
|
||||
|
||||
QScriptValue EntityItemPropertiesToScriptValue(QScriptEngine* engine, const EntityItemProperties& properties) {
|
||||
return properties.copyToScriptValue(engine);
|
||||
return properties.copyToScriptValue(engine, false);
|
||||
}
|
||||
|
||||
QScriptValue EntityItemNonDefaultPropertiesToScriptValue(QScriptEngine* engine, const EntityItemProperties& properties) {
|
||||
return properties.copyToScriptValue(engine, true);
|
||||
}
|
||||
|
||||
void EntityItemPropertiesFromScriptValue(const QScriptValue &object, EntityItemProperties& properties) {
|
||||
|
|
|
@ -159,7 +159,7 @@ public:
|
|||
EntityTypes::EntityType getType() const { return _type; }
|
||||
void setType(EntityTypes::EntityType type) { _type = type; }
|
||||
|
||||
virtual QScriptValue copyToScriptValue(QScriptEngine* engine) const;
|
||||
virtual QScriptValue copyToScriptValue(QScriptEngine* engine, bool skipDefaults) const;
|
||||
virtual void copyFromScriptValue(const QScriptValue& object);
|
||||
|
||||
// editing related features supported by all entities
|
||||
|
@ -307,6 +307,7 @@ private:
|
|||
};
|
||||
Q_DECLARE_METATYPE(EntityItemProperties);
|
||||
QScriptValue EntityItemPropertiesToScriptValue(QScriptEngine* engine, const EntityItemProperties& properties);
|
||||
QScriptValue EntityItemNonDefaultPropertiesToScriptValue(QScriptEngine* engine, const EntityItemProperties& properties);
|
||||
void EntityItemPropertiesFromScriptValue(const QScriptValue &object, EntityItemProperties& properties);
|
||||
|
||||
|
||||
|
|
|
@ -198,26 +198,41 @@
|
|||
|
||||
|
||||
#define COPY_PROPERTY_TO_QSCRIPTVALUE_VEC3(P) \
|
||||
QScriptValue P = vec3toScriptValue(engine, _##P); \
|
||||
properties.setProperty(#P, P);
|
||||
if (!skipDefaults || defaultEntityProperties._##P != _##P) { \
|
||||
QScriptValue P = vec3toScriptValue(engine, _##P); \
|
||||
properties.setProperty(#P, P); \
|
||||
}
|
||||
|
||||
#define COPY_PROPERTY_TO_QSCRIPTVALUE_QUAT(P) \
|
||||
QScriptValue P = quatToScriptValue(engine, _##P); \
|
||||
properties.setProperty(#P, P);
|
||||
if (!skipDefaults || defaultEntityProperties._##P != _##P) { \
|
||||
QScriptValue P = quatToScriptValue(engine, _##P); \
|
||||
properties.setProperty(#P, P); \
|
||||
}
|
||||
|
||||
#define COPY_PROPERTY_TO_QSCRIPTVALUE_COLOR(P) \
|
||||
QScriptValue P = xColorToScriptValue(engine, _##P); \
|
||||
properties.setProperty(#P, P);
|
||||
if (!skipDefaults || defaultEntityProperties._##P != _##P) { \
|
||||
QScriptValue P = xColorToScriptValue(engine, _##P); \
|
||||
properties.setProperty(#P, P); \
|
||||
}
|
||||
|
||||
#define COPY_PROPERTY_TO_QSCRIPTVALUE_COLOR_GETTER(P,G) \
|
||||
QScriptValue P = xColorToScriptValue(engine, G); \
|
||||
properties.setProperty(#P, P);
|
||||
if (!skipDefaults || defaultEntityProperties._##P != _##P) { \
|
||||
QScriptValue P = xColorToScriptValue(engine, G); \
|
||||
properties.setProperty(#P, P); \
|
||||
}
|
||||
|
||||
#define COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(P, G) \
|
||||
#define COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(P, G) \
|
||||
properties.setProperty(#P, G);
|
||||
|
||||
#define COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(P, G) \
|
||||
if (!skipDefaults || defaultEntityProperties._##P != _##P) { \
|
||||
properties.setProperty(#P, G); \
|
||||
}
|
||||
|
||||
#define COPY_PROPERTY_TO_QSCRIPTVALUE(P) \
|
||||
properties.setProperty(#P, _##P);
|
||||
if (!skipDefaults || defaultEntityProperties._##P != _##P) { \
|
||||
properties.setProperty(#P, _##P); \
|
||||
}
|
||||
|
||||
#define COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(P, S) \
|
||||
QScriptValue P = object.property(#P); \
|
||||
|
|
|
@ -1137,10 +1137,10 @@ bool EntityTree::sendEntitiesOperation(OctreeElement* element, void* extraData)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool EntityTree::writeToMap(QVariantMap& entityDescription, OctreeElement* element) {
|
||||
bool EntityTree::writeToMap(QVariantMap& entityDescription, OctreeElement* element, bool skipDefaultValues) {
|
||||
entityDescription["Entities"] = QVariantList();
|
||||
QScriptEngine scriptEngine;
|
||||
RecurseOctreeToMapOperator theOperator(entityDescription, element, &scriptEngine);
|
||||
RecurseOctreeToMapOperator theOperator(entityDescription, element, &scriptEngine, skipDefaultValues);
|
||||
recurseTreeWithOperator(&theOperator);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -163,7 +163,7 @@ public:
|
|||
bool wantEditLogging() const { return _wantEditLogging; }
|
||||
void setWantEditLogging(bool value) { _wantEditLogging = value; }
|
||||
|
||||
bool writeToMap(QVariantMap& entityDescription, OctreeElement* element);
|
||||
bool writeToMap(QVariantMap& entityDescription, OctreeElement* element, bool skipDefaultValues);
|
||||
bool readFromMap(QVariantMap& entityDescription);
|
||||
|
||||
signals:
|
||||
|
|
|
@ -12,11 +12,15 @@
|
|||
#include "RecurseOctreeToMapOperator.h"
|
||||
|
||||
|
||||
RecurseOctreeToMapOperator::RecurseOctreeToMapOperator(QVariantMap& map, OctreeElement *top, QScriptEngine *engine) :
|
||||
RecurseOctreeToMapOperator::RecurseOctreeToMapOperator(QVariantMap& map,
|
||||
OctreeElement *top,
|
||||
QScriptEngine *engine,
|
||||
bool skipDefaultValues) :
|
||||
RecurseOctreeOperator(),
|
||||
_map(map),
|
||||
_top(top),
|
||||
_engine(engine)
|
||||
_engine(engine),
|
||||
_skipDefaultValues(skipDefaultValues)
|
||||
{
|
||||
// if some element "top" was given, only save information for that element and it's children.
|
||||
if (_top) {
|
||||
|
@ -36,6 +40,8 @@ bool RecurseOctreeToMapOperator::preRecursion(OctreeElement* element) {
|
|||
|
||||
bool RecurseOctreeToMapOperator::postRecursion(OctreeElement* element) {
|
||||
|
||||
EntityItemProperties defaultProperties;
|
||||
|
||||
EntityTreeElement* entityTreeElement = static_cast<EntityTreeElement*>(element);
|
||||
const QList<EntityItem*>& entities = entityTreeElement->getEntities();
|
||||
|
||||
|
@ -43,7 +49,12 @@ bool RecurseOctreeToMapOperator::postRecursion(OctreeElement* element) {
|
|||
|
||||
foreach (EntityItem* entityItem, entities) {
|
||||
EntityItemProperties properties = entityItem->getProperties();
|
||||
QScriptValue qScriptValues = EntityItemPropertiesToScriptValue(_engine, properties);
|
||||
QScriptValue qScriptValues;
|
||||
if (_skipDefaultValues) {
|
||||
qScriptValues = EntityItemNonDefaultPropertiesToScriptValue(_engine, properties);
|
||||
} else {
|
||||
qScriptValues = EntityItemPropertiesToScriptValue(_engine, properties);
|
||||
}
|
||||
entitiesQList << qScriptValues.toVariant();
|
||||
}
|
||||
_map["Entities"] = entitiesQList;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
class RecurseOctreeToMapOperator : public RecurseOctreeOperator {
|
||||
public:
|
||||
RecurseOctreeToMapOperator(QVariantMap& map, OctreeElement *top, QScriptEngine *engine);
|
||||
RecurseOctreeToMapOperator(QVariantMap& map, OctreeElement *top, QScriptEngine *engine, bool skipDefaultValues);
|
||||
bool preRecursion(OctreeElement* element);
|
||||
bool postRecursion(OctreeElement* element);
|
||||
private:
|
||||
|
@ -21,4 +21,5 @@ public:
|
|||
OctreeElement *_top;
|
||||
QScriptEngine *_engine;
|
||||
bool _withinTop;
|
||||
bool _skipDefaultValues;
|
||||
};
|
||||
|
|
|
@ -203,6 +203,16 @@ public:
|
|||
glm::quat rotation; // relative orientation
|
||||
};
|
||||
|
||||
inline bool operator==(const SittingPoint& lhs, const SittingPoint& rhs)
|
||||
{
|
||||
return (lhs.name == rhs.name) && (lhs.position == rhs.position) && (lhs.rotation == rhs.rotation);
|
||||
}
|
||||
|
||||
inline bool operator!=(const SittingPoint& lhs, const SittingPoint& rhs)
|
||||
{
|
||||
return (lhs.name != rhs.name) || (lhs.position != rhs.position) || (lhs.rotation != rhs.rotation);
|
||||
}
|
||||
|
||||
/// A set of meshes extracted from an FBX document.
|
||||
class FBXGeometry {
|
||||
public:
|
||||
|
|
|
@ -2087,7 +2087,7 @@ void Octree::writeToJSONFile(const char* fileName, OctreeElement* element) {
|
|||
QFile persistFile(fileName);
|
||||
QVariantMap entityDescription;
|
||||
|
||||
qCDebug(octree, "Saving to file %s...", fileName);
|
||||
qCDebug(octree, "Saving JSON SVO to file %s...", fileName);
|
||||
|
||||
OctreeElement* top;
|
||||
if (element) {
|
||||
|
@ -2096,7 +2096,7 @@ void Octree::writeToJSONFile(const char* fileName, OctreeElement* element) {
|
|||
top = _rootElement;
|
||||
}
|
||||
|
||||
bool entityDescriptionSuccess = writeToMap(entityDescription, top);
|
||||
bool entityDescriptionSuccess = writeToMap(entityDescription, top, true);
|
||||
if (entityDescriptionSuccess && persistFile.open(QIODevice::WriteOnly)) {
|
||||
persistFile.write(QJsonDocument::fromVariant(entityDescription).toJson());
|
||||
} else {
|
||||
|
@ -2108,7 +2108,7 @@ void Octree::writeToSVOFile(const char* fileName, OctreeElement* element) {
|
|||
std::ofstream file(fileName, std::ios::out|std::ios::binary);
|
||||
|
||||
if(file.is_open()) {
|
||||
qCDebug(octree, "Saving to file %s...", fileName);
|
||||
qCDebug(octree, "Saving binary SVO to file %s...", fileName);
|
||||
|
||||
PacketType expectedType = expectedDataPacketType();
|
||||
PacketVersion expectedVersion = versionForPacketType(expectedType);
|
||||
|
|
|
@ -331,7 +331,7 @@ public:
|
|||
void writeToFile(const char* filename, OctreeElement* element = NULL, QString persistAsFileType = "svo");
|
||||
void writeToJSONFile(const char* filename, OctreeElement* element = NULL);
|
||||
void writeToSVOFile(const char* filename, OctreeElement* element = NULL);
|
||||
virtual bool writeToMap(QVariantMap& entityDescription, OctreeElement* element) = 0;
|
||||
virtual bool writeToMap(QVariantMap& entityDescription, OctreeElement* element, bool skipDefaultValues) = 0;
|
||||
|
||||
// Octree importers
|
||||
bool readFromFile(const char* filename);
|
||||
|
|
|
@ -43,6 +43,17 @@ inline QDebug& operator<<(QDebug& dbg, const xColor& c) {
|
|||
return dbg;
|
||||
}
|
||||
|
||||
inline bool operator==(const xColor& lhs, const xColor& rhs)
|
||||
{
|
||||
return (lhs.red == rhs.red) && (lhs.green == rhs.green) && (lhs.blue == rhs.blue);
|
||||
}
|
||||
|
||||
inline bool operator!=(const xColor& lhs, const xColor& rhs)
|
||||
{
|
||||
return (lhs.red != rhs.red) || (lhs.green != rhs.green) || (lhs.blue != rhs.blue);
|
||||
}
|
||||
|
||||
|
||||
static const float ZERO = 0.0f;
|
||||
static const float ONE = 1.0f;
|
||||
static const float ONE_HALF = 0.5f;
|
||||
|
|
Loading…
Reference in a new issue