mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-04-08 06:32:35 +02:00
Merge remote-tracking branch 'upstream/master' into plugins
This commit is contained in:
commit
19d31938d3
45 changed files with 1342 additions and 52 deletions
225
examples/example/painting/hydraPaint.js
Normal file
225
examples/example/painting/hydraPaint.js
Normal file
|
@ -0,0 +1,225 @@
|
|||
//
|
||||
// hydraPaint.js
|
||||
// examples
|
||||
//
|
||||
// Created by Eric Levin on 5/14/15.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// This script allows you to paint with the hydra!
|
||||
//
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
var LEFT = 0;
|
||||
var RIGHT = 1;
|
||||
var LASER_WIDTH = 3;
|
||||
var LASER_COLOR = {
|
||||
red: 50,
|
||||
green: 150,
|
||||
blue: 200
|
||||
};
|
||||
var TRIGGER_THRESHOLD = .1;
|
||||
|
||||
var MAX_POINTS_PER_LINE = 40;
|
||||
|
||||
var LIFETIME = 6000;
|
||||
var DRAWING_DEPTH = 1;
|
||||
var LINE_DIMENSIONS = 20;
|
||||
|
||||
|
||||
var MIN_POINT_DISTANCE = 0.01;
|
||||
|
||||
var MIN_BRUSH_RADIUS = 0.08;
|
||||
var MAX_BRUSH_RADIUS = 0.1;
|
||||
|
||||
var RIGHT_BUTTON_1 = 7
|
||||
var RIGHT_BUTTON_2 = 8
|
||||
var RIGHT_BUTTON_3 = 9;
|
||||
var RIGHT_BUTTON_4 = 10
|
||||
var LEFT_BUTTON_1 = 1;
|
||||
var LEFT_BUTTON_2 = 2;
|
||||
var LEFT_BUTTON_3 = 3;
|
||||
var LEFT_BUTTON_4 = 4;
|
||||
|
||||
var colorPalette = [{
|
||||
red: 250,
|
||||
green: 0,
|
||||
blue: 0
|
||||
}, {
|
||||
red: 214,
|
||||
green: 91,
|
||||
blue: 67
|
||||
}, {
|
||||
red: 192,
|
||||
green: 41,
|
||||
blue: 66
|
||||
}, {
|
||||
red: 84,
|
||||
green: 36,
|
||||
blue: 55
|
||||
}, {
|
||||
red: 83,
|
||||
green: 119,
|
||||
blue: 122
|
||||
}];
|
||||
|
||||
var MIN_STROKE_WIDTH = 0.002;
|
||||
var MAX_STROKE_WIDTH = 0.05;
|
||||
|
||||
function controller(side, cycleColorButton) {
|
||||
this.triggerHeld = false;
|
||||
this.triggerThreshold = 0.9;
|
||||
this.side = side;
|
||||
this.palm = 2 * side;
|
||||
this.tip = 2 * side + 1;
|
||||
this.trigger = side;
|
||||
this.cycleColorButton = cycleColorButton;
|
||||
|
||||
this.points = [];
|
||||
this.normals = [];
|
||||
this.strokeWidths = [];
|
||||
|
||||
this.currentColorIndex = 0;
|
||||
this.currentColor = colorPalette[this.currentColorIndex];
|
||||
|
||||
var self = this;
|
||||
|
||||
|
||||
this.brush = Entities.addEntity({
|
||||
type: 'Sphere',
|
||||
position: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0
|
||||
},
|
||||
color: this.currentColor,
|
||||
dimensions: {
|
||||
x: MIN_BRUSH_RADIUS,
|
||||
y: MIN_BRUSH_RADIUS,
|
||||
z: MIN_BRUSH_RADIUS
|
||||
}
|
||||
});
|
||||
|
||||
this.cycleColor = function() {
|
||||
this.currentColor = colorPalette[++this.currentColorIndex];
|
||||
if (this.currentColorIndex === colorPalette.length - 1) {
|
||||
this.currentColorIndex = -1;
|
||||
}
|
||||
}
|
||||
this.newLine = function(position) {
|
||||
this.linePosition = position;
|
||||
this.line = Entities.addEntity({
|
||||
position: position,
|
||||
type: "PolyLine",
|
||||
color: this.currentColor,
|
||||
dimensions: {
|
||||
x: LINE_DIMENSIONS,
|
||||
y: LINE_DIMENSIONS,
|
||||
z: LINE_DIMENSIONS
|
||||
},
|
||||
lifetime: LIFETIME
|
||||
});
|
||||
this.points = [];
|
||||
this.normals = []
|
||||
this.strokeWidths = [];
|
||||
}
|
||||
|
||||
this.update = function(deltaTime) {
|
||||
this.updateControllerState();
|
||||
var newBrushPosOffset = Vec3.multiply(Vec3.normalize(Vec3.subtract(this.tipPosition, this.palmPosition)), DRAWING_DEPTH);
|
||||
var newBrushPos = Vec3.sum(this.palmPosition, newBrushPosOffset);
|
||||
var brushRadius = map(this.triggerValue, TRIGGER_THRESHOLD, 1, MIN_BRUSH_RADIUS, MAX_BRUSH_RADIUS)
|
||||
Entities.editEntity(this.brush, {
|
||||
position: newBrushPos,
|
||||
color: this.currentColor,
|
||||
dimensions: {
|
||||
x: brushRadius,
|
||||
y: brushRadius,
|
||||
z: brushRadius
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if (this.triggerValue > TRIGGER_THRESHOLD && !this.drawing) {
|
||||
this.newLine(newBrushPos);
|
||||
this.drawing = true;
|
||||
} else if (this.drawing && this.triggerValue < TRIGGER_THRESHOLD) {
|
||||
this.drawing = false;
|
||||
}
|
||||
|
||||
if (this.drawing && this.points.length < MAX_POINTS_PER_LINE) {
|
||||
var localPoint = Vec3.subtract(newBrushPos, this.linePosition);
|
||||
if (Vec3.distance(localPoint, this.points[this.points.length - 1]) < MIN_POINT_DISTANCE) {
|
||||
//Need a minimum distance to avoid binormal NANs
|
||||
return;
|
||||
}
|
||||
|
||||
this.points.push(localPoint);
|
||||
var normal = computeNormal(newBrushPos, Camera.getPosition());
|
||||
|
||||
this.normals.push(normal);
|
||||
var strokeWidth = map(this.triggerValue, TRIGGER_THRESHOLD, 1, MIN_STROKE_WIDTH, MAX_STROKE_WIDTH);
|
||||
this.strokeWidths.push(strokeWidth);
|
||||
Entities.editEntity(this.line, {
|
||||
linePoints: this.points,
|
||||
normals: this.normals,
|
||||
strokeWidths: this.strokeWidths,
|
||||
color: this.currentColor
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.updateControllerState = function() {
|
||||
this.cycleColorButtonPressed = Controller.isButtonPressed(this.cycleColorButton);
|
||||
this.palmPosition = Controller.getSpatialControlPosition(this.palm);
|
||||
this.tipPosition = Controller.getSpatialControlPosition(this.tip);
|
||||
this.palmNormal = Controller.getSpatialControlNormal(this.palm);
|
||||
this.triggerValue = Controller.getTriggerValue(this.trigger);
|
||||
|
||||
|
||||
if (this.prevCycleColorButtonPressed === true && this.cycleColorButtonPressed === false) {
|
||||
this.cycleColor();
|
||||
Entities.editEntity(this.brush, {
|
||||
// color: this.currentColor
|
||||
});
|
||||
}
|
||||
|
||||
this.prevCycleColorButtonPressed = this.cycleColorButtonPressed;
|
||||
|
||||
}
|
||||
|
||||
this.cleanup = function() {
|
||||
Entities.deleteEntity(self.brush);
|
||||
}
|
||||
}
|
||||
|
||||
function computeNormal(p1, p2) {
|
||||
return Vec3.normalize(Vec3.subtract(p2, p1));
|
||||
}
|
||||
|
||||
function update(deltaTime) {
|
||||
leftController.update(deltaTime);
|
||||
rightController.update(deltaTime);
|
||||
}
|
||||
|
||||
function scriptEnding() {
|
||||
leftController.cleanup();
|
||||
rightController.cleanup();
|
||||
}
|
||||
|
||||
function vectorIsZero(v) {
|
||||
return v.x === 0 && v.y === 0 && v.z === 0;
|
||||
}
|
||||
|
||||
|
||||
var rightController = new controller(RIGHT, RIGHT_BUTTON_4);
|
||||
var leftController = new controller(LEFT, LEFT_BUTTON_4);
|
||||
Script.update.connect(update);
|
||||
Script.scriptEnding.connect(scriptEnding);
|
||||
|
||||
function map(value, min1, max1, min2, max2) {
|
||||
return min2 + (max2 - min2) * ((value - min1) / (max1 - min1));
|
||||
}
|
194
examples/example/painting/mousePaint.js
Normal file
194
examples/example/painting/mousePaint.js
Normal file
|
@ -0,0 +1,194 @@
|
|||
//
|
||||
// mousePaint.js
|
||||
// examples
|
||||
//
|
||||
// Created by Eric Levin on 6/4/15.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// This script allows you to paint with the hydra or mouse!
|
||||
//
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
var LINE_DIMENSIONS = 10;
|
||||
var LIFETIME = 6000;
|
||||
var EVENT_CHANGE_THRESHOLD = 200;
|
||||
var LINE_WIDTH = .07;
|
||||
var MAX_POINTS_PER_LINE = 40;
|
||||
var points = [];
|
||||
var normals = [];
|
||||
var deletedLines = [];
|
||||
var strokeWidths = [];
|
||||
var count = 0;
|
||||
var prevEvent = {x: 0, y: 0};
|
||||
var eventChange;
|
||||
|
||||
var MIN_POINT_DISTANCE = .01;
|
||||
|
||||
var colorPalette = [{
|
||||
red: 250,
|
||||
green: 0,
|
||||
blue: 0
|
||||
}, {
|
||||
red: 214,
|
||||
green: 91,
|
||||
blue: 67
|
||||
}, {
|
||||
red: 192,
|
||||
green: 41,
|
||||
blue: 66
|
||||
}, {
|
||||
red: 84,
|
||||
green: 36,
|
||||
blue: 55
|
||||
}, {
|
||||
red: 83,
|
||||
green: 119,
|
||||
blue: 122
|
||||
}];
|
||||
|
||||
var currentColorIndex = 0;
|
||||
var currentColor = colorPalette[currentColorIndex];
|
||||
|
||||
function cycleColor() {
|
||||
currentColor = colorPalette[++currentColorIndex];
|
||||
if (currentColorIndex === colorPalette.length - 1) {
|
||||
currentColorIndex = -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
MousePaint();
|
||||
|
||||
function MousePaint() {
|
||||
var DRAWING_DISTANCE = 5;
|
||||
var lines = [];
|
||||
var isDrawing = false;
|
||||
|
||||
var line, linePosition;
|
||||
|
||||
var BRUSH_SIZE = .05;
|
||||
|
||||
var brush = Entities.addEntity({
|
||||
type: 'Sphere',
|
||||
position: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0
|
||||
},
|
||||
color: currentColor,
|
||||
dimensions: {
|
||||
x: BRUSH_SIZE,
|
||||
y: BRUSH_SIZE,
|
||||
z: BRUSH_SIZE
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
function newLine(position) {
|
||||
linePosition = position;
|
||||
line = Entities.addEntity({
|
||||
position: position,
|
||||
type: "PolyLine",
|
||||
color: currentColor,
|
||||
dimensions: {
|
||||
x: LINE_DIMENSIONS,
|
||||
y: LINE_DIMENSIONS,
|
||||
z: LINE_DIMENSIONS
|
||||
},
|
||||
linePoints: [],
|
||||
lifetime: LIFETIME
|
||||
});
|
||||
points = [];
|
||||
normals = []
|
||||
strokeWidths = [];
|
||||
lines.push(line);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function mouseMoveEvent(event) {
|
||||
|
||||
var pickRay = Camera.computePickRay(event.x, event.y);
|
||||
count++;
|
||||
var worldPoint = computeWorldPoint(pickRay);
|
||||
Entities.editEntity(brush, {
|
||||
position: worldPoint
|
||||
});
|
||||
|
||||
eventChange = Math.sqrt(Math.pow(event.x - prevEvent.x, 2) + Math.pow(event.y - prevEvent.y, 2));
|
||||
localPoint = computeLocalPoint(worldPoint);
|
||||
if (!isDrawing || points.length > MAX_POINTS_PER_LINE || eventChange > EVENT_CHANGE_THRESHOLD ||
|
||||
Vec3.distance(points[points.length - 1], localPoint) < MIN_POINT_DISTANCE) {
|
||||
return;
|
||||
}
|
||||
|
||||
points.push(localPoint)
|
||||
normals.push(computeNormal(worldPoint, pickRay.origin));
|
||||
strokeWidths.push(LINE_WIDTH);
|
||||
Entities.editEntity(line, {
|
||||
strokeWidths: strokeWidths,
|
||||
linePoints: points,
|
||||
normals: normals,
|
||||
});
|
||||
prevEvent = event;
|
||||
}
|
||||
|
||||
function computeNormal(p1, p2) {
|
||||
return Vec3.normalize(Vec3.subtract(p2, p1));
|
||||
}
|
||||
|
||||
function computeWorldPoint(pickRay) {
|
||||
var addVector = Vec3.multiply(Vec3.normalize(pickRay.direction), DRAWING_DISTANCE);
|
||||
return Vec3.sum(pickRay.origin, addVector);
|
||||
}
|
||||
|
||||
function computeLocalPoint(worldPoint) {
|
||||
var localPoint = Vec3.subtract(worldPoint, linePosition);
|
||||
return localPoint;
|
||||
}
|
||||
|
||||
function mousePressEvent(event) {
|
||||
if (!event.isLeftButton) {
|
||||
isDrawing = false;
|
||||
return;
|
||||
}
|
||||
var pickRay = Camera.computePickRay(event.x, event.y);
|
||||
prevEvent = {x: event.x, y:event.y};
|
||||
var worldPoint = computeWorldPoint(pickRay);
|
||||
newLine(worldPoint);
|
||||
var localPoint = computeLocalPoint(worldPoint);
|
||||
points.push(localPoint);
|
||||
normals.push(computeNormal(worldPoint, pickRay.origin));
|
||||
strokeWidths.push(0.07);
|
||||
isDrawing = true;
|
||||
}
|
||||
|
||||
function mouseReleaseEvent() {
|
||||
isDrawing = false;
|
||||
}
|
||||
|
||||
function keyPressEvent(event) {
|
||||
if (event.text === "SPACE") {
|
||||
cycleColor();
|
||||
Entities.editEntity(brush, {
|
||||
color: currentColor
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
lines.forEach(function(line) {
|
||||
// Entities.deleteEntity(line);
|
||||
});
|
||||
Entities.deleteEntity(brush);
|
||||
}
|
||||
|
||||
Controller.mousePressEvent.connect(mousePressEvent);
|
||||
Controller.mouseReleaseEvent.connect(mouseReleaseEvent);
|
||||
Controller.mouseMoveEvent.connect(mouseMoveEvent);
|
||||
Script.scriptEnding.connect(cleanup);
|
||||
|
||||
Controller.keyPressEvent.connect(keyPressEvent);
|
||||
}
|
|
@ -595,7 +595,7 @@ function menuItemEvent(menuItem) {
|
|||
LODManager.LODDecreased.connect(function() {
|
||||
var warningText = "\n"
|
||||
+ "Due to the complexity of the content, the \n"
|
||||
+ "level of detail has been decreased."
|
||||
+ "level of detail has been decreased. "
|
||||
+ "You can now see: \n"
|
||||
+ LODManager.getLODFeedbackText();
|
||||
|
||||
|
|
BIN
interface/resources/images/paintStroke.png
Normal file
BIN
interface/resources/images/paintStroke.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
|
@ -815,7 +815,7 @@ void Application::initializeGL() {
|
|||
init();
|
||||
qCDebug(interfaceapp, "init() complete.");
|
||||
|
||||
// create thread for parsing of octee data independent of the main network and rendering threads
|
||||
// create thread for parsing of octree data independent of the main network and rendering threads
|
||||
_octreeProcessor.initialize(_enableProcessOctreeThread);
|
||||
connect(&_octreeProcessor, &OctreePacketProcessor::packetVersionMismatch, this, &Application::notifyPacketVersionMismatch);
|
||||
_entityEditSender.initialize(_enableProcessOctreeThread);
|
||||
|
|
|
@ -107,12 +107,14 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
|
|||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||
|
||||
Rig::HeadParameters params;
|
||||
params.modelRotation = getRotation();
|
||||
params.modelTranslation = getTranslation();
|
||||
params.leanSideways = _owningAvatar->getHead()->getFinalLeanSideways();
|
||||
params.leanForward = _owningAvatar->getHead()->getFinalLeanSideways();
|
||||
params.torsoTwist = _owningAvatar->getHead()->getTorsoTwist();
|
||||
params.localHeadOrientation = _owningAvatar->getHead()->getFinalOrientationInLocalFrame();
|
||||
params.worldHeadOrientation = _owningAvatar->getHead()->getFinalOrientationInWorldFrame();
|
||||
params.eyeLookAt = _owningAvatar->getHead()->getCorrectedLookAtPosition();
|
||||
params.eyeLookAt = _owningAvatar->getHead()->getLookAtPosition();
|
||||
params.eyeSaccade = _owningAvatar->getHead()->getSaccade();
|
||||
params.leanJointIndex = geometry.leanJointIndex;
|
||||
params.neckJointIndex = geometry.neckJointIndex;
|
||||
|
|
|
@ -230,11 +230,13 @@ void JointState::setRotationInConstrainedFrame(glm::quat targetRotation, float p
|
|||
}
|
||||
|
||||
void JointState::setRotationInConstrainedFrameInternal(const glm::quat& targetRotation) {
|
||||
glm::quat parentRotation = computeParentRotation();
|
||||
_rotationInConstrainedFrame = targetRotation;
|
||||
_transformChanged = true;
|
||||
// R' = Rp * Rpre * r' * Rpost
|
||||
_rotation = parentRotation * _preRotation * _rotationInConstrainedFrame * _postRotation;
|
||||
if (_rotationInConstrainedFrame != targetRotation) {
|
||||
glm::quat parentRotation = computeParentRotation();
|
||||
_rotationInConstrainedFrame = targetRotation;
|
||||
_transformChanged = true;
|
||||
// R' = Rp * Rpre * r' * Rpost
|
||||
_rotation = parentRotation * _preRotation * _rotationInConstrainedFrame * _postRotation;
|
||||
}
|
||||
}
|
||||
|
||||
void JointState::setVisibleRotationInConstrainedFrame(const glm::quat& targetRotation) {
|
||||
|
|
|
@ -27,6 +27,10 @@ void Rig::HeadParameters::dump() const {
|
|||
axis = glm::axis(worldHeadOrientation);
|
||||
theta = glm::angle(worldHeadOrientation);
|
||||
qCDebug(animation, " worldHeadOrientation axis = (%.5f, %.5f, %.5f), theta = %0.5f", axis.x, axis.y, axis.z, theta);
|
||||
axis = glm::axis(modelRotation);
|
||||
theta = glm::angle(modelRotation);
|
||||
qCDebug(animation, " modelRotation axis = (%.5f, %.5f, %.5f), theta = %0.5f", axis.x, axis.y, axis.z, theta);
|
||||
qCDebug(animation, " modelTranslation = (%.5f, %.5f, %.5f)", modelTranslation.x, modelTranslation.y, modelTranslation.z);
|
||||
qCDebug(animation, " eyeLookAt = (%.5f, %.5f, %.5f)", eyeLookAt.x, eyeLookAt.y, eyeLookAt.z);
|
||||
qCDebug(animation, " eyeSaccade = (%.5f, %.5f, %.5f)", eyeSaccade.x, eyeSaccade.y, eyeSaccade.z);
|
||||
qCDebug(animation, " leanJointIndex = %.d", leanJointIndex);
|
||||
|
@ -782,8 +786,8 @@ glm::quat Rig::getJointDefaultRotationInParentFrame(int jointIndex) {
|
|||
void Rig::updateFromHeadParameters(const HeadParameters& params) {
|
||||
updateLeanJoint(params.leanJointIndex, params.leanSideways, params.leanForward, params.torsoTwist);
|
||||
updateNeckJoint(params.neckJointIndex, params.localHeadOrientation, params.leanSideways, params.leanForward, params.torsoTwist);
|
||||
updateEyeJoint(params.leftEyeJointIndex, params.worldHeadOrientation, params.eyeLookAt, params.eyeSaccade);
|
||||
updateEyeJoint(params.rightEyeJointIndex, params.worldHeadOrientation, params.eyeLookAt, params.eyeSaccade);
|
||||
updateEyeJoint(params.leftEyeJointIndex, params.modelTranslation, params.modelRotation, params.worldHeadOrientation, params.eyeLookAt, params.eyeSaccade);
|
||||
updateEyeJoint(params.rightEyeJointIndex, params.modelTranslation, params.modelRotation, params.worldHeadOrientation, params.eyeLookAt, params.eyeSaccade);
|
||||
}
|
||||
|
||||
void Rig::updateLeanJoint(int index, float leanSideways, float leanForward, float torsoTwist) {
|
||||
|
@ -824,22 +828,21 @@ void Rig::updateNeckJoint(int index, const glm::quat& localHeadOrientation, floa
|
|||
}
|
||||
}
|
||||
|
||||
void Rig::updateEyeJoint(int index, const glm::quat& worldHeadOrientation, const glm::vec3& lookAt, const glm::vec3& saccade) {
|
||||
void Rig::updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm::quat& modelRotation, const glm::quat& worldHeadOrientation, const glm::vec3& lookAtSpot, const glm::vec3& saccade) {
|
||||
if (index >= 0 && _jointStates[index].getParentIndex() >= 0) {
|
||||
auto& state = _jointStates[index];
|
||||
auto& parentState = _jointStates[state.getParentIndex()];
|
||||
|
||||
// NOTE: at the moment we do the math in the world-frame, hence the inverse transform is more complex than usual.
|
||||
glm::mat4 inverse = glm::inverse(parentState.getTransform() *
|
||||
glm::translate(getJointDefaultTranslationInConstrainedFrame(index)) *
|
||||
glm::mat4 inverse = glm::inverse(glm::mat4_cast(modelRotation) * parentState.getTransform() *
|
||||
glm::translate(state.getDefaultTranslationInConstrainedFrame()) *
|
||||
state.getPreTransform() * glm::mat4_cast(state.getPreRotation() * state.getDefaultRotation()));
|
||||
glm::vec3 front = glm::vec3(inverse * glm::vec4(worldHeadOrientation * IDENTITY_FRONT, 0.0f));
|
||||
glm::vec3 lookAtDelta = lookAt;
|
||||
glm::vec3 lookAtDelta = lookAtSpot - modelTranslation;
|
||||
glm::vec3 lookAt = glm::vec3(inverse * glm::vec4(lookAtDelta + glm::length(lookAtDelta) * saccade, 1.0f));
|
||||
glm::quat between = rotationBetween(front, lookAt);
|
||||
const float MAX_ANGLE = 30.0f * RADIANS_PER_DEGREE;
|
||||
float angle = glm::clamp(glm::angle(between), -MAX_ANGLE, MAX_ANGLE);
|
||||
glm::quat rot = glm::angleAxis(angle, glm::axis(between));
|
||||
setJointRotationInConstrainedFrame(index, rot * state.getDefaultRotation(), DEFAULT_PRIORITY);
|
||||
state.setRotationInConstrainedFrame(glm::angleAxis(glm::clamp(glm::angle(between), -MAX_ANGLE, MAX_ANGLE), glm::axis(between)) *
|
||||
state.getDefaultRotation(), DEFAULT_PRIORITY);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,10 +54,12 @@ public:
|
|||
float leanSideways = 0.0f; // degrees
|
||||
float leanForward = 0.0f; // degrees
|
||||
float torsoTwist = 0.0f; // degrees
|
||||
glm::quat modelRotation = glm::quat();
|
||||
glm::quat localHeadOrientation = glm::quat();
|
||||
glm::quat worldHeadOrientation = glm::quat();
|
||||
glm::vec3 eyeLookAt = glm::vec3(); // world space
|
||||
glm::vec3 eyeSaccade = glm::vec3(); // world space
|
||||
glm::vec3 modelTranslation = glm::vec3();
|
||||
int leanJointIndex = -1;
|
||||
int neckJointIndex = -1;
|
||||
int leftEyeJointIndex = -1;
|
||||
|
@ -163,7 +165,7 @@ public:
|
|||
|
||||
void updateLeanJoint(int index, float leanSideways, float leanForward, float torsoTwist);
|
||||
void updateNeckJoint(int index, const glm::quat& localHeadOrientation, float leanSideways, float leanForward, float torsoTwist);
|
||||
void updateEyeJoint(int index, const glm::quat& worldHeadOrientation, const glm::vec3& lookAt, const glm::vec3& saccade);
|
||||
void updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm::quat& modelRotation, const glm::quat& worldHeadOrientation, const glm::vec3& lookAt, const glm::vec3& saccade);
|
||||
|
||||
QVector<JointState> _jointStates;
|
||||
int _rootJointIndex = -1;
|
||||
|
|
78
libraries/entities-renderer/src/DeferredBufferWrite.slh
Executable file
78
libraries/entities-renderer/src/DeferredBufferWrite.slh
Executable file
|
@ -0,0 +1,78 @@
|
|||
<!
|
||||
// DeferredBufferWrite.slh
|
||||
// libraries/render-utils/src
|
||||
//
|
||||
// Created by Sam Gateau on 1/12/15.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
!>
|
||||
<@if not DEFERRED_BUFFER_WRITE_SLH@>
|
||||
<@def DEFERRED_BUFFER_WRITE_SLH@>
|
||||
|
||||
layout(location = 0) out vec4 _fragColor0;
|
||||
layout(location = 1) out vec4 _fragColor1;
|
||||
layout(location = 2) out vec4 _fragColor2;
|
||||
|
||||
// the glow intensity
|
||||
uniform float glowIntensity;
|
||||
|
||||
// the alpha threshold
|
||||
uniform float alphaThreshold;
|
||||
|
||||
uniform sampler2D normalFittingMap;
|
||||
|
||||
vec3 bestFitNormal(vec3 normal) {
|
||||
vec3 absNorm = abs(normal);
|
||||
float maxNAbs = max(absNorm.z, max(absNorm.x, absNorm.y));
|
||||
|
||||
vec2 texcoord = (absNorm.z < maxNAbs ?
|
||||
(absNorm.y < maxNAbs ? absNorm.yz : absNorm.xz) :
|
||||
absNorm.xy);
|
||||
texcoord = (texcoord.x < texcoord.y ? texcoord.yx : texcoord.xy);
|
||||
texcoord.y /= texcoord.x;
|
||||
vec3 cN = normal / maxNAbs;
|
||||
float fittingScale = texture(normalFittingMap, texcoord).a;
|
||||
cN *= fittingScale;
|
||||
return (cN * 0.5 + 0.5);
|
||||
}
|
||||
|
||||
float evalOpaqueFinalAlpha(float alpha, float mapAlpha) {
|
||||
return mix(alpha * glowIntensity, 1.0 - alpha * glowIntensity, step(mapAlpha, alphaThreshold));
|
||||
}
|
||||
|
||||
const vec3 DEFAULT_SPECULAR = vec3(0.1);
|
||||
const float DEFAULT_SHININESS = 10;
|
||||
|
||||
void packDeferredFragment(vec3 normal, float alpha, vec3 diffuse, vec3 specular, float shininess) {
|
||||
if (alpha != glowIntensity) {
|
||||
discard;
|
||||
}
|
||||
_fragColor0 = vec4(diffuse.rgb, alpha);
|
||||
_fragColor1 = vec4(bestFitNormal(normal), 1.0);
|
||||
_fragColor2 = vec4(specular, shininess / 128.0);
|
||||
}
|
||||
|
||||
void packDeferredFragmentLightmap(vec3 normal, float alpha, vec3 diffuse, vec3 specular, float shininess, vec3 emissive) {
|
||||
if (alpha != glowIntensity) {
|
||||
discard;
|
||||
}
|
||||
|
||||
_fragColor0 = vec4(diffuse.rgb, alpha);
|
||||
//_fragColor1 = vec4(normal, 0.0) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0);
|
||||
_fragColor1 = vec4(bestFitNormal(normal), 0.5);
|
||||
_fragColor2 = vec4(emissive, shininess / 128.0);
|
||||
}
|
||||
|
||||
void packDeferredFragmentTranslucent(vec3 normal, float alpha, vec3 diffuse, vec3 specular, float shininess) {
|
||||
if (alpha <= alphaThreshold) {
|
||||
discard;
|
||||
}
|
||||
|
||||
_fragColor0 = vec4(diffuse.rgb, alpha);
|
||||
// _fragColor1 = vec4(normal, 0.0) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0);
|
||||
// _fragColor2 = vec4(specular, shininess / 128.0);
|
||||
}
|
||||
|
||||
<@endif@>
|
|
@ -38,6 +38,7 @@
|
|||
#include "RenderableZoneEntityItem.h"
|
||||
#include "RenderableLineEntityItem.h"
|
||||
#include "RenderablePolyVoxEntityItem.h"
|
||||
#include "RenderablePolyLineEntityItem.h"
|
||||
#include "EntitiesRendererLogging.h"
|
||||
#include "AddressManager.h"
|
||||
#include "EntityRig.h"
|
||||
|
@ -66,6 +67,7 @@ EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterf
|
|||
REGISTER_ENTITY_TYPE_WITH_FACTORY(Zone, RenderableZoneEntityItem::factory)
|
||||
REGISTER_ENTITY_TYPE_WITH_FACTORY(Line, RenderableLineEntityItem::factory)
|
||||
REGISTER_ENTITY_TYPE_WITH_FACTORY(PolyVox, RenderablePolyVoxEntityItem::factory)
|
||||
REGISTER_ENTITY_TYPE_WITH_FACTORY(PolyLine, RenderablePolyLineEntityItem::factory)
|
||||
|
||||
_currentHoverOverEntityID = UNKNOWN_ENTITY_ID;
|
||||
_currentClickingOnEntityID = UNKNOWN_ENTITY_ID;
|
||||
|
|
|
@ -18,6 +18,9 @@ namespace render {
|
|||
if (payload->entity->getType() == EntityTypes::Light) {
|
||||
return ItemKey::Builder::light();
|
||||
}
|
||||
if (payload && payload->entity->getType() == EntityTypes::PolyLine) {
|
||||
return ItemKey::Builder::transparentShape();
|
||||
}
|
||||
}
|
||||
return ItemKey::Builder::opaqueShape();
|
||||
}
|
||||
|
|
|
@ -35,6 +35,9 @@ void RenderableLineEntityItem::updateGeometry() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void RenderableLineEntityItem::render(RenderArgs* args) {
|
||||
PerformanceTimer perfTimer("RenderableLineEntityItem::render");
|
||||
Q_ASSERT(getType() == EntityTypes::Line);
|
||||
|
|
|
@ -275,9 +275,12 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
|
|||
}
|
||||
|
||||
if (jointsMapped()) {
|
||||
auto frameData = getAnimationFrame();
|
||||
for (int i = 0; i < frameData.size(); i++) {
|
||||
_model->setJointState(i, true, frameData[i]);
|
||||
bool newFrame;
|
||||
auto frameData = getAnimationFrame(newFrame);
|
||||
if (newFrame) {
|
||||
for (int i = 0; i < frameData.size(); i++) {
|
||||
_model->setJointState(i, true, frameData[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
158
libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp
Normal file
158
libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp
Normal file
|
@ -0,0 +1,158 @@
|
|||
//
|
||||
// RenderablePolyLineEntityItem.cpp
|
||||
// libraries/entities-renderer/src/
|
||||
//
|
||||
// Created by Eric Levin on 8/10/15
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
|
||||
#include <GeometryCache.h>
|
||||
#include <TextureCache.h>
|
||||
#include <PathUtils.h>
|
||||
#include <DeferredLightingEffect.h>
|
||||
#include <PerfStat.h>
|
||||
|
||||
#include "RenderablePolyLineEntityItem.h"
|
||||
|
||||
#include "paintStroke_vert.h"
|
||||
#include "paintStroke_frag.h"
|
||||
|
||||
|
||||
|
||||
EntityItemPointer RenderablePolyLineEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
return EntityItemPointer(new RenderablePolyLineEntityItem(entityID, properties));
|
||||
}
|
||||
|
||||
RenderablePolyLineEntityItem::RenderablePolyLineEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
||||
PolyLineEntityItem(entityItemID, properties) {
|
||||
_numVertices = 0;
|
||||
|
||||
}
|
||||
|
||||
gpu::PipelinePointer RenderablePolyLineEntityItem::_pipeline;
|
||||
gpu::Stream::FormatPointer RenderablePolyLineEntityItem::_format;
|
||||
gpu::TexturePointer RenderablePolyLineEntityItem::_texture;
|
||||
GLint RenderablePolyLineEntityItem::PAINTSTROKE_GPU_SLOT;
|
||||
|
||||
void RenderablePolyLineEntityItem::createPipeline() {
|
||||
static const int NORMAL_OFFSET = 12;
|
||||
static const int COLOR_OFFSET = 24;
|
||||
static const int TEXTURE_OFFSET = 28;
|
||||
|
||||
auto textureCache = DependencyManager::get<TextureCache>();
|
||||
QString path = PathUtils::resourcesPath() + "images/paintStroke.png";
|
||||
_texture = textureCache->getImageTexture(path);
|
||||
_format.reset(new gpu::Stream::Format());
|
||||
_format->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);
|
||||
_format->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), NORMAL_OFFSET);
|
||||
_format->setAttribute(gpu::Stream::COLOR, 0, gpu::Element::COLOR_RGBA_32, COLOR_OFFSET);
|
||||
_format->setAttribute(gpu::Stream::TEXCOORD, 0, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV), TEXTURE_OFFSET);
|
||||
|
||||
auto VS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(paintStroke_vert)));
|
||||
auto PS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(paintStroke_frag)));
|
||||
gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(VS, PS));
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
PAINTSTROKE_GPU_SLOT = 0;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("paintStrokeTextureBinding"), PAINTSTROKE_GPU_SLOT));
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
state->setDepthTest(true, true, gpu::LESS_EQUAL);
|
||||
state->setBlendFunction(true,
|
||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||
_pipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state));
|
||||
}
|
||||
|
||||
void RenderablePolyLineEntityItem::updateGeometry() {
|
||||
_numVertices = 0;
|
||||
_verticesBuffer.reset(new gpu::Buffer());
|
||||
int vertexIndex = 0;
|
||||
vec2 uv;
|
||||
float tailStart = 0.0f;
|
||||
float tailEnd = 0.25f;
|
||||
float tailLength = tailEnd - tailStart;
|
||||
|
||||
float headStart = 0.76f;
|
||||
float headEnd = 1.0f;
|
||||
float headLength = headEnd - headStart;
|
||||
float uCoord, vCoord;
|
||||
|
||||
int numTailStrips = 5;
|
||||
int numHeadStrips = 10;
|
||||
int startHeadIndex = _normals.size() - numHeadStrips;
|
||||
for (int i = 0; i < _normals.size(); i++) {
|
||||
uCoord = 0.26f;
|
||||
vCoord = 0.0f;
|
||||
//tail
|
||||
if(i < numTailStrips) {
|
||||
uCoord = float(i)/numTailStrips * tailLength + tailStart;
|
||||
}
|
||||
|
||||
//head
|
||||
if( i > startHeadIndex) {
|
||||
uCoord = float( (i+ 1) - startHeadIndex)/numHeadStrips * headLength + headStart;
|
||||
}
|
||||
|
||||
uv = vec2(uCoord, vCoord);
|
||||
|
||||
_verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_vertices.at(vertexIndex));
|
||||
_verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_normals.at(i));
|
||||
_verticesBuffer->append(sizeof(int), (gpu::Byte*)&_color);
|
||||
_verticesBuffer->append(sizeof(glm::vec2), (gpu::Byte*)&uv);
|
||||
vertexIndex++;
|
||||
|
||||
uv.y = 1.0f;
|
||||
_verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_vertices.at(vertexIndex));
|
||||
_verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_normals.at(i));
|
||||
_verticesBuffer->append(sizeof(int), (gpu::Byte*)_color);
|
||||
_verticesBuffer->append(sizeof(glm::vec2), (const gpu::Byte*)&uv);
|
||||
vertexIndex++;
|
||||
|
||||
_numVertices +=2;
|
||||
}
|
||||
_pointsChanged = false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void RenderablePolyLineEntityItem::render(RenderArgs* args) {
|
||||
QWriteLocker lock(&_quadReadWriteLock);
|
||||
if (_points.size() < 2 || _vertices.size() != _normals.size() * 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_pipeline) {
|
||||
createPipeline();
|
||||
}
|
||||
|
||||
PerformanceTimer perfTimer("RenderablePolyLineEntityItem::render");
|
||||
Q_ASSERT(getType() == EntityTypes::PolyLine);
|
||||
|
||||
Q_ASSERT(args->_batch);
|
||||
if (_pointsChanged) {
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
gpu::Batch& batch = *args->_batch;
|
||||
Transform transform = Transform();
|
||||
transform.setTranslation(getPosition());
|
||||
transform.setRotation(getRotation());
|
||||
batch.setModelTransform(transform);
|
||||
|
||||
batch.setPipeline(_pipeline);
|
||||
batch.setResourceTexture(PAINTSTROKE_GPU_SLOT, _texture);
|
||||
|
||||
batch.setInputFormat(_format);
|
||||
batch.setInputBuffer(0, _verticesBuffer, 0, _format->getChannels().at(0)._stride);
|
||||
|
||||
batch.draw(gpu::TRIANGLE_STRIP, _numVertices, 0);
|
||||
|
||||
RenderableDebugableEntityItem::render(this, args);
|
||||
};
|
|
@ -0,0 +1,47 @@
|
|||
//
|
||||
// RenderablePolyLineEntityItem.h
|
||||
// libraries/entities-renderer/src/
|
||||
//
|
||||
// Created by Eric Levin on 6/22/15.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_RenderablePolyLineEntityItem_h
|
||||
#define hifi_RenderablePolyLineEntityItem_h
|
||||
|
||||
#include <gpu/Batch.h>
|
||||
#include <PolyLineEntityItem.h>
|
||||
#include "RenderableDebugableEntityItem.h"
|
||||
#include "RenderableEntityItem.h"
|
||||
#include <GeometryCache.h>
|
||||
#include <QReadWriteLock>
|
||||
#include <gpu/GPUConfig.h>
|
||||
|
||||
|
||||
class RenderablePolyLineEntityItem : public PolyLineEntityItem {
|
||||
public:
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
static void createPipeline();
|
||||
RenderablePolyLineEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
||||
|
||||
virtual void render(RenderArgs* args);
|
||||
|
||||
SIMPLE_RENDERABLE();
|
||||
|
||||
static gpu::PipelinePointer _pipeline;
|
||||
static gpu::Stream::FormatPointer _format;
|
||||
static gpu::TexturePointer _texture;
|
||||
static GLint PAINTSTROKE_GPU_SLOT;
|
||||
|
||||
protected:
|
||||
void updateGeometry();
|
||||
gpu::BufferPointer _verticesBuffer;
|
||||
unsigned int _numVertices;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // hifi_RenderablePolyLineEntityItem_h
|
|
@ -40,7 +40,7 @@
|
|||
#include "EntityTreeRenderer.h"
|
||||
#include "polyvox_vert.h"
|
||||
#include "polyvox_frag.h"
|
||||
#include "RenderablePolyVoxEntityItem.h"
|
||||
#include "RenderablePolyVoxEntityItem.h"
|
||||
|
||||
gpu::PipelinePointer RenderablePolyVoxEntityItem::_pipeline = nullptr;
|
||||
|
||||
|
|
45
libraries/entities-renderer/src/paintStroke.slf
Normal file
45
libraries/entities-renderer/src/paintStroke.slf
Normal file
|
@ -0,0 +1,45 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// paintStroke.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Eric Levin on 8/10/2015
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D originalTexture;
|
||||
|
||||
// the interpolated normal
|
||||
in vec3 interpolatedNormal;
|
||||
in vec2 varTexcoord;
|
||||
in vec4 varColor;
|
||||
|
||||
float rand(vec2 point){
|
||||
return fract(sin(dot(point.xy ,vec2(12.9898,78.233))) * 43758.5453);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void main(void) {
|
||||
|
||||
|
||||
vec4 texel = texture(originalTexture, varTexcoord);
|
||||
int frontCondition = 1 -int(gl_FrontFacing) * 2;
|
||||
vec3 color = varColor.rgb;
|
||||
//vec3 normal, float alpha, vec3 diffuse, vec3 specular, float shininess
|
||||
packDeferredFragmentTranslucent(
|
||||
interpolatedNormal * frontCondition,
|
||||
texel.a,
|
||||
color *texel.rgb,
|
||||
vec3(0.01, 0.01, 0.01),
|
||||
10.0);
|
||||
}
|
40
libraries/entities-renderer/src/paintStroke.slv
Normal file
40
libraries/entities-renderer/src/paintStroke.slv
Normal file
|
@ -0,0 +1,40 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// paintStroke.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Eric Levin on 7/20/15.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
<@include gpu/Inputs.slh@>
|
||||
<@include gpu/Transform.slh@>
|
||||
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
// the interpolated normal
|
||||
out vec3 interpolatedNormal;
|
||||
|
||||
//the diffuse texture
|
||||
out vec2 varTexcoord;
|
||||
|
||||
out vec4 varColor;
|
||||
|
||||
void main(void) {
|
||||
|
||||
varTexcoord = inTexCoord0.st;
|
||||
|
||||
// pass along the diffuse color
|
||||
varColor = inColor;
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToClipPos(cam, obj, inPosition, gl_Position)$>
|
||||
<$transformModelToEyeDir(cam, obj, inNormal.xyz, interpolatedNormal)$>
|
||||
}
|
|
@ -28,6 +28,7 @@
|
|||
#include "ZoneEntityItem.h"
|
||||
#include "PolyVoxEntityItem.h"
|
||||
#include "LineEntityItem.h"
|
||||
#include "PolyLineEntityItem.h"
|
||||
|
||||
AtmospherePropertyGroup EntityItemProperties::_staticAtmosphere;
|
||||
SkyboxPropertyGroup EntityItemProperties::_staticSkybox;
|
||||
|
@ -102,6 +103,8 @@ CONSTRUCT_PROPERTY(lineWidth, LineEntityItem::DEFAULT_LINE_WIDTH),
|
|||
CONSTRUCT_PROPERTY(linePoints, QVector<glm::vec3>()),
|
||||
CONSTRUCT_PROPERTY(faceCamera, TextEntityItem::DEFAULT_FACE_CAMERA),
|
||||
CONSTRUCT_PROPERTY(actionData, QByteArray()),
|
||||
CONSTRUCT_PROPERTY(normals, QVector<glm::vec3>()),
|
||||
CONSTRUCT_PROPERTY(strokeWidths, QVector<float>()),
|
||||
CONSTRUCT_PROPERTY(xTextureURL, ""),
|
||||
CONSTRUCT_PROPERTY(yTextureURL, ""),
|
||||
CONSTRUCT_PROPERTY(zTextureURL, ""),
|
||||
|
@ -367,6 +370,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|||
CHECK_PROPERTY_CHANGE(PROP_DESCRIPTION, description);
|
||||
CHECK_PROPERTY_CHANGE(PROP_FACE_CAMERA, faceCamera);
|
||||
CHECK_PROPERTY_CHANGE(PROP_ACTION_DATA, actionData);
|
||||
CHECK_PROPERTY_CHANGE(PROP_NORMALS, normals);
|
||||
CHECK_PROPERTY_CHANGE(PROP_STROKE_WIDTHS, strokeWidths);
|
||||
CHECK_PROPERTY_CHANGE(PROP_X_TEXTURE_URL, xTextureURL);
|
||||
CHECK_PROPERTY_CHANGE(PROP_Y_TEXTURE_URL, yTextureURL);
|
||||
CHECK_PROPERTY_CHANGE(PROP_Z_TEXTURE_URL, zTextureURL);
|
||||
|
@ -469,6 +474,8 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
|||
COPY_PROPERTY_TO_QSCRIPTVALUE(description);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(faceCamera);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(actionData);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(normals);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(strokeWidths);
|
||||
|
||||
// Sitting properties support
|
||||
if (!skipDefaults) {
|
||||
|
@ -587,6 +594,8 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
|
|||
COPY_PROPERTY_FROM_QSCRIPTVALUE(description, QString, setDescription);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(faceCamera, bool, setFaceCamera);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(actionData, QByteArray, setActionData);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(normals, qVectorVec3, setNormals);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(strokeWidths,qVectorFloat, setStrokeWidths);
|
||||
|
||||
if (!honorReadOnly) {
|
||||
// this is used by the json reader to set things that we don't want javascript to able to affect.
|
||||
|
@ -843,6 +852,14 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType::Value command, Ent
|
|||
APPEND_ENTITY_PROPERTY(PROP_LINE_WIDTH, properties.getLineWidth());
|
||||
APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, properties.getLinePoints());
|
||||
}
|
||||
|
||||
if (properties.getType() == EntityTypes::PolyLine) {
|
||||
APPEND_ENTITY_PROPERTY(PROP_LINE_WIDTH, properties.getLineWidth());
|
||||
APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, properties.getLinePoints());
|
||||
APPEND_ENTITY_PROPERTY(PROP_NORMALS, properties.getNormals());
|
||||
APPEND_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, properties.getStrokeWidths());
|
||||
}
|
||||
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, properties.getMarketplaceID());
|
||||
APPEND_ENTITY_PROPERTY(PROP_NAME, properties.getName());
|
||||
|
@ -1097,6 +1114,14 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
|||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_WIDTH, float, setLineWidth);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_POINTS, QVector<glm::vec3>, setLinePoints);
|
||||
}
|
||||
|
||||
|
||||
if (properties.getType() == EntityTypes::PolyLine) {
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_WIDTH, float, setLineWidth);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_POINTS, QVector<glm::vec3>, setLinePoints);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_NORMALS, QVector<glm::vec3>, setNormals);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_STROKE_WIDTHS, QVector<float>, setStrokeWidths);
|
||||
}
|
||||
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MARKETPLACE_ID, QString, setMarketplaceID);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_NAME, QString, setName);
|
||||
|
@ -1215,6 +1240,9 @@ void EntityItemProperties::markAllChanged() {
|
|||
_descriptionChanged = true;
|
||||
_faceCameraChanged = true;
|
||||
_actionDataChanged = true;
|
||||
|
||||
_normalsChanged = true;
|
||||
_strokeWidthsChanged = true;
|
||||
|
||||
_xTextureURLChanged = true;
|
||||
_yTextureURLChanged = true;
|
||||
|
|
|
@ -56,6 +56,7 @@ class EntityItemProperties {
|
|||
friend class WebEntityItem; // TODO: consider removing this friend relationship and use public methods
|
||||
friend class LineEntityItem; // TODO: consider removing this friend relationship and use public methods
|
||||
friend class PolyVoxEntityItem; // TODO: consider removing this friend relationship and use public methods
|
||||
friend class PolyLineEntityItem; // TODO: consider removing this friend relationship and use public methods
|
||||
public:
|
||||
EntityItemProperties();
|
||||
virtual ~EntityItemProperties();
|
||||
|
@ -153,6 +154,8 @@ public:
|
|||
DEFINE_PROPERTY_REF(PROP_HREF, Href, href, QString);
|
||||
DEFINE_PROPERTY_REF(PROP_DESCRIPTION, Description, description, QString);
|
||||
DEFINE_PROPERTY(PROP_FACE_CAMERA, FaceCamera, faceCamera, bool);
|
||||
DEFINE_PROPERTY(PROP_NORMALS, Normals, normals, QVector<glm::vec3>);
|
||||
DEFINE_PROPERTY(PROP_STROKE_WIDTHS, StrokeWidths, strokeWidths, QVector<float>);
|
||||
DEFINE_PROPERTY_REF(PROP_ACTION_DATA, ActionData, actionData, QByteArray);
|
||||
DEFINE_PROPERTY_REF(PROP_X_TEXTURE_URL, XTextureURL, xTextureURL, QString);
|
||||
DEFINE_PROPERTY_REF(PROP_Y_TEXTURE_URL, YTextureURL, yTextureURL, QString);
|
||||
|
|
|
@ -98,7 +98,8 @@ inline QScriptValue convertScriptValue(QScriptEngine* e, const QString& v) { ret
|
|||
inline QScriptValue convertScriptValue(QScriptEngine* e, const xColor& v) { return xColorToScriptValue(e, v); }
|
||||
inline QScriptValue convertScriptValue(QScriptEngine* e, const glm::quat& v) { return quatToScriptValue(e, v); }
|
||||
inline QScriptValue convertScriptValue(QScriptEngine* e, const QScriptValue& v) { return v; }
|
||||
inline QScriptValue convertScriptValue(QScriptEngine* e, const QVector<glm::vec3>& v) {return qVectorVec3ToScriptValue(e, v); }
|
||||
inline QScriptValue convertScriptValue(QScriptEngine* e, const QVector<glm::vec3>& v) {return qVectorVec3ToScriptValue(e, v); }
|
||||
inline QScriptValue convertScriptValue(QScriptEngine* e, const QVector<float>& v) { return qVectorFloatToScriptValue(e, v); }
|
||||
|
||||
inline QScriptValue convertScriptValue(QScriptEngine* e, const QByteArray& v) {
|
||||
QByteArray b64 = v.toBase64();
|
||||
|
@ -134,6 +135,7 @@ inline QScriptValue convertScriptValue(QScriptEngine* e, const QByteArray& v) {
|
|||
typedef glm::vec3 glmVec3;
|
||||
typedef glm::quat glmQuat;
|
||||
typedef QVector<glm::vec3> qVectorVec3;
|
||||
typedef QVector<float> qVectorFloat;
|
||||
inline float float_convertFromScriptValue(const QScriptValue& v, bool& isValid) { return v.toVariant().toFloat(&isValid); }
|
||||
inline quint64 quint64_convertFromScriptValue(const QScriptValue& v, bool& isValid) { return v.toVariant().toULongLong(&isValid); }
|
||||
inline uint16_t uint16_t_convertFromScriptValue(const QScriptValue& v, bool& isValid) { return v.toVariant().toInt(&isValid); }
|
||||
|
@ -177,6 +179,11 @@ inline glmVec3 glmVec3_convertFromScriptValue(const QScriptValue& v, bool& isVal
|
|||
return glm::vec3(0);
|
||||
}
|
||||
|
||||
inline qVectorFloat qVectorFloat_convertFromScriptValue(const QScriptValue& v, bool& isValid) {
|
||||
isValid = true;
|
||||
return qVectorFloatFromScriptValue(v);
|
||||
}
|
||||
|
||||
inline qVectorVec3 qVectorVec3_convertFromScriptValue(const QScriptValue& v, bool& isValid) {
|
||||
isValid = true;
|
||||
return qVectorVec3FromScriptValue(v);
|
||||
|
|
|
@ -124,11 +124,17 @@ enum EntityPropertyList {
|
|||
|
||||
PROP_FACE_CAMERA,
|
||||
PROP_SCRIPT_TIMESTAMP,
|
||||
|
||||
PROP_ACTION_DATA,
|
||||
|
||||
|
||||
PROP_X_TEXTURE_URL, // used by PolyVox
|
||||
PROP_Y_TEXTURE_URL, // used by PolyVox
|
||||
PROP_Z_TEXTURE_URL, // used by PolyVox
|
||||
|
||||
// Used by PolyLine entity
|
||||
PROP_NORMALS,
|
||||
PROP_STROKE_WIDTHS,
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// ATTENTION: add new properties to end of list just ABOVE this line
|
||||
|
|
|
@ -455,18 +455,18 @@ bool EntityScriptingInterface::setPoints(QUuid entityID, std::function<bool(Line
|
|||
if (!_entityTree) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
EntityItemPointer entity = static_cast<EntityItemPointer>(_entityTree->findEntityByEntityItemID(entityID));
|
||||
if (!entity) {
|
||||
qCDebug(entities) << "EntityScriptingInterface::setPoints no entity with ID" << entityID;
|
||||
}
|
||||
|
||||
|
||||
EntityTypes::EntityType entityType = entity->getType();
|
||||
|
||||
|
||||
if (entityType != EntityTypes::Line) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
auto now = usecTimestampNow();
|
||||
|
||||
auto lineEntity = std::static_pointer_cast<LineEntityItem>(entity);
|
||||
|
@ -475,19 +475,20 @@ bool EntityScriptingInterface::setPoints(QUuid entityID, std::function<bool(Line
|
|||
entity->setLastEdited(now);
|
||||
entity->setLastBroadcast(now);
|
||||
_entityTree->unlock();
|
||||
|
||||
|
||||
_entityTree->lockForRead();
|
||||
EntityItemProperties properties = entity->getProperties();
|
||||
_entityTree->unlock();
|
||||
|
||||
|
||||
properties.setLinePointsDirty();
|
||||
properties.setLastEdited(now);
|
||||
|
||||
|
||||
|
||||
|
||||
queueEntityMessage(PacketType::EntityEdit, entityID, properties);
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
bool EntityScriptingInterface::setVoxelSphere(QUuid entityID, const glm::vec3& center, float radius, int value) {
|
||||
return setVoxels(entityID, [center, radius, value](PolyVoxEntityItem& polyVoxEntity) {
|
||||
polyVoxEntity.setSphere(center, radius, value);
|
||||
|
@ -507,17 +508,39 @@ bool EntityScriptingInterface::setAllVoxels(QUuid entityID, int value) {
|
|||
}
|
||||
|
||||
bool EntityScriptingInterface::setAllPoints(QUuid entityID, const QVector<glm::vec3>& points) {
|
||||
return setPoints(entityID, [points](LineEntityItem& lineEntity) -> bool
|
||||
{
|
||||
return lineEntity.setLinePoints(points);
|
||||
});
|
||||
EntityItemPointer entity = static_cast<EntityItemPointer>(_entityTree->findEntityByEntityItemID(entityID));
|
||||
if (!entity) {
|
||||
qCDebug(entities) << "EntityScriptingInterface::setPoints no entity with ID" << entityID;
|
||||
}
|
||||
|
||||
EntityTypes::EntityType entityType = entity->getType();
|
||||
|
||||
if (entityType == EntityTypes::Line) {
|
||||
return setPoints(entityID, [points](LineEntityItem& lineEntity) -> bool
|
||||
{
|
||||
return (LineEntityItem*)lineEntity.setLinePoints(points);
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EntityScriptingInterface::appendPoint(QUuid entityID, const glm::vec3& point) {
|
||||
return setPoints(entityID, [point](LineEntityItem& lineEntity) -> bool
|
||||
{
|
||||
return lineEntity.appendPoint(point);
|
||||
});
|
||||
EntityItemPointer entity = static_cast<EntityItemPointer>(_entityTree->findEntityByEntityItemID(entityID));
|
||||
if (!entity) {
|
||||
qCDebug(entities) << "EntityScriptingInterface::setPoints no entity with ID" << entityID;
|
||||
}
|
||||
|
||||
EntityTypes::EntityType entityType = entity->getType();
|
||||
|
||||
if (entityType == EntityTypes::Line) {
|
||||
return setPoints(entityID, [point](LineEntityItem& lineEntity) -> bool
|
||||
{
|
||||
return (LineEntityItem*)lineEntity.appendPoint(point);
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <RegisteredMetaTypes.h>
|
||||
#include "PolyVoxEntityItem.h"
|
||||
#include "LineEntityItem.h"
|
||||
#include "PolyLineEntityItem.h"
|
||||
|
||||
#include "EntityEditPacketSender.h"
|
||||
|
||||
|
@ -165,6 +166,7 @@ private:
|
|||
bool setPoints(QUuid entityID, std::function<bool(LineEntityItem&)> actor);
|
||||
void queueEntityMessage(PacketType::Value packetType, EntityItemID entityID, const EntityItemProperties& properties);
|
||||
|
||||
|
||||
/// actually does the work of finding the ray intersection, can be called in locking mode or tryLock mode
|
||||
RayToEntityIntersectionResult findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType,
|
||||
bool precisionPicking);
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "ZoneEntityItem.h"
|
||||
#include "LineEntityItem.h"
|
||||
#include "PolyVoxEntityItem.h"
|
||||
#include "PolyLineEntityItem.h"
|
||||
|
||||
QMap<EntityTypes::EntityType, QString> EntityTypes::_typeToNameMap;
|
||||
QMap<QString, EntityTypes::EntityType> EntityTypes::_nameToTypeMap;
|
||||
|
@ -47,6 +48,7 @@ REGISTER_ENTITY_TYPE(ParticleEffect)
|
|||
REGISTER_ENTITY_TYPE(Zone)
|
||||
REGISTER_ENTITY_TYPE(Line)
|
||||
REGISTER_ENTITY_TYPE(PolyVox)
|
||||
REGISTER_ENTITY_TYPE(PolyLine);
|
||||
|
||||
const QString& EntityTypes::getEntityTypeName(EntityType entityType) {
|
||||
QMap<EntityType, QString>::iterator matchedTypeName = _typeToNameMap.find(entityType);
|
||||
|
|
|
@ -47,7 +47,8 @@ public:
|
|||
Web,
|
||||
Line,
|
||||
PolyVox,
|
||||
LAST = PolyVox
|
||||
PolyLine,
|
||||
LAST = PolyLine
|
||||
} EntityType;
|
||||
|
||||
static const QString& getEntityTypeName(EntityType entityType);
|
||||
|
|
|
@ -218,7 +218,8 @@ void ModelEntityItem::mapJoints(const QStringList& modelJointNames) {
|
|||
}
|
||||
}
|
||||
|
||||
const QVector<glm::quat>& ModelEntityItem::getAnimationFrame() {
|
||||
const QVector<glm::quat>& ModelEntityItem::getAnimationFrame(bool& newFrame) {
|
||||
newFrame = false;
|
||||
|
||||
if (!hasAnimation() || !_jointMappingCompleted) {
|
||||
return _lastKnownFrameData;
|
||||
|
@ -238,6 +239,7 @@ const QVector<glm::quat>& ModelEntityItem::getAnimationFrame() {
|
|||
|
||||
if (animationFrameIndex != _lastKnownFrameIndex) {
|
||||
_lastKnownFrameIndex = animationFrameIndex;
|
||||
newFrame = true;
|
||||
|
||||
const QVector<glm::quat>& rotations = frames[animationFrameIndex].rotations;
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ public:
|
|||
float getAnimationLastFrame() const { return _animationLoop.getLastFrame(); }
|
||||
|
||||
void mapJoints(const QStringList& modelJointNames);
|
||||
const QVector<glm::quat>& getAnimationFrame();
|
||||
const QVector<glm::quat>& getAnimationFrame(bool& newFrame);
|
||||
bool jointsMapped() const { return _jointMappingCompleted; }
|
||||
|
||||
bool getAnimationIsPlaying() const { return _animationLoop.isRunning(); }
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
//
|
||||
// ParticleEffectEntityItem.cpp
|
||||
// libraries/entities/src
|
||||
|
|
238
libraries/entities/src/PolyLineEntityItem.cpp
Normal file
238
libraries/entities/src/PolyLineEntityItem.cpp
Normal file
|
@ -0,0 +1,238 @@
|
|||
//
|
||||
// PolyLineEntityItem.cpp
|
||||
// libraries/entities/src
|
||||
//
|
||||
// Created by Eric Levin on 6/22/15.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include <ByteCountCoding.h>
|
||||
|
||||
#include "PolyLineEntityItem.h"
|
||||
#include "EntityTree.h"
|
||||
#include "EntitiesLogging.h"
|
||||
#include "EntityTreeElement.h"
|
||||
#include "OctreeConstants.h"
|
||||
|
||||
|
||||
|
||||
const float PolyLineEntityItem::DEFAULT_LINE_WIDTH = 0.1f;
|
||||
const int PolyLineEntityItem::MAX_POINTS_PER_LINE = 70;
|
||||
|
||||
|
||||
EntityItemPointer PolyLineEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
EntityItemPointer result { new PolyLineEntityItem(entityID, properties) };
|
||||
return result;
|
||||
}
|
||||
|
||||
PolyLineEntityItem::PolyLineEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
||||
EntityItem(entityItemID) ,
|
||||
_lineWidth(DEFAULT_LINE_WIDTH),
|
||||
_pointsChanged(true),
|
||||
_points(QVector<glm::vec3>(0.0f)),
|
||||
_vertices(QVector<glm::vec3>(0.0f)),
|
||||
_normals(QVector<glm::vec3>(0.0f)),
|
||||
_strokeWidths(QVector<float>(0.0f))
|
||||
{
|
||||
_type = EntityTypes::PolyLine;
|
||||
_created = properties.getCreated();
|
||||
setProperties(properties);
|
||||
}
|
||||
|
||||
EntityItemProperties PolyLineEntityItem::getProperties() const {
|
||||
QWriteLocker lock(&_quadReadWriteLock);
|
||||
EntityItemProperties properties = EntityItem::getProperties(); // get the properties from our base class
|
||||
|
||||
|
||||
properties._color = getXColor();
|
||||
properties._colorChanged = false;
|
||||
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(lineWidth, getLineWidth);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(linePoints, getLinePoints);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(normals, getNormals);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(strokeWidths, getStrokeWidths);
|
||||
|
||||
properties._glowLevel = getGlowLevel();
|
||||
properties._glowLevelChanged = false;
|
||||
return properties;
|
||||
}
|
||||
|
||||
bool PolyLineEntityItem::setProperties(const EntityItemProperties& properties) {
|
||||
QWriteLocker lock(&_quadReadWriteLock);
|
||||
bool somethingChanged = false;
|
||||
somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class
|
||||
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(lineWidth, setLineWidth);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(linePoints, setLinePoints);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(normals, setNormals);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(strokeWidths, setStrokeWidths);
|
||||
|
||||
if (somethingChanged) {
|
||||
bool wantDebug = false;
|
||||
if (wantDebug) {
|
||||
uint64_t now = usecTimestampNow();
|
||||
int elapsed = now - getLastEdited();
|
||||
qCDebug(entities) << "PolyLineEntityItem::setProperties() AFTER update... edited AGO=" << elapsed <<
|
||||
"now=" << now << " getLastEdited()=" << getLastEdited();
|
||||
}
|
||||
setLastEdited(properties._lastEdited);
|
||||
}
|
||||
return somethingChanged;
|
||||
}
|
||||
|
||||
bool PolyLineEntityItem::appendPoint(const glm::vec3& point) {
|
||||
if (_points.size() > MAX_POINTS_PER_LINE - 1) {
|
||||
qDebug() << "MAX POINTS REACHED!";
|
||||
return false;
|
||||
}
|
||||
glm::vec3 halfBox = getDimensions() * 0.5f;
|
||||
if ( (point.x < - halfBox.x || point.x > halfBox.x) || (point.y < -halfBox.y || point.y > halfBox.y) || (point.z < - halfBox.z || point.z > halfBox.z) ) {
|
||||
qDebug() << "Point is outside entity's bounding box";
|
||||
return false;
|
||||
}
|
||||
_points << point;
|
||||
_pointsChanged = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PolyLineEntityItem::setStrokeWidths(const QVector<float>& strokeWidths ) {
|
||||
_strokeWidths = strokeWidths;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PolyLineEntityItem::setNormals(const QVector<glm::vec3>& normals) {
|
||||
_normals = normals;
|
||||
if (_points.size () < 2 || _normals.size() < 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int minVectorSize = _normals.size();
|
||||
if (_points.size() < minVectorSize) {
|
||||
minVectorSize = _points.size();
|
||||
}
|
||||
if (_strokeWidths.size() < minVectorSize) {
|
||||
minVectorSize = _strokeWidths.size();
|
||||
}
|
||||
|
||||
_vertices.clear();
|
||||
glm::vec3 v1, v2, tangent, binormal, point;
|
||||
|
||||
for (int i = 0; i < minVectorSize-1; i++) {
|
||||
float width = _strokeWidths.at(i);
|
||||
point = _points.at(i);
|
||||
|
||||
tangent = _points.at(i+1) - point;
|
||||
glm::vec3 normal = normals.at(i);
|
||||
binormal = glm::normalize(glm::cross(tangent, normal)) * width;
|
||||
|
||||
//This checks to make sure binormal is not a NAN
|
||||
assert(binormal.x == binormal.x);
|
||||
v1 = point + binormal;
|
||||
v2 = point - binormal;
|
||||
_vertices << v1 << v2;
|
||||
}
|
||||
//for last point we can just assume binormals are same since it represents last two vertices of quad
|
||||
point = _points.at(_points.size() - 1);
|
||||
v1 = point + binormal;
|
||||
v2 = point - binormal;
|
||||
_vertices << v1 << v2;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PolyLineEntityItem::setLinePoints(const QVector<glm::vec3>& points) {
|
||||
if (points.size() > MAX_POINTS_PER_LINE) {
|
||||
return false;
|
||||
}
|
||||
if (points.size() != _points.size()) {
|
||||
_pointsChanged = true;
|
||||
}
|
||||
//Check to see if points actually changed. If they haven't, return before doing anything else
|
||||
else if (points.size() == _points.size()) {
|
||||
//same number of points, so now compare every point
|
||||
for (int i = 0; i < points.size(); i++ ) {
|
||||
if (points.at(i) != _points.at(i)){
|
||||
_pointsChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!_pointsChanged) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < points.size(); i++) {
|
||||
glm::vec3 point = points.at(i);
|
||||
glm::vec3 pos = getPosition();
|
||||
glm::vec3 halfBox = getDimensions() * 0.5f;
|
||||
if ( (point.x < - halfBox.x || point.x > halfBox.x) || (point.y < -halfBox.y || point.y > halfBox.y) || (point.z < - halfBox.z || point.z > halfBox.z) ) {
|
||||
qDebug() << "Point is outside entity's bounding box";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
_points = points;
|
||||
return true;
|
||||
}
|
||||
|
||||
int PolyLineEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
||||
ReadBitstreamToTreeParams& args,
|
||||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData) {
|
||||
QWriteLocker lock(&_quadReadWriteLock);
|
||||
int bytesRead = 0;
|
||||
const unsigned char* dataAt = data;
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_COLOR, rgbColor, setColor);
|
||||
READ_ENTITY_PROPERTY(PROP_LINE_WIDTH, float, setLineWidth);
|
||||
READ_ENTITY_PROPERTY(PROP_LINE_POINTS, QVector<glm::vec3>, setLinePoints);
|
||||
READ_ENTITY_PROPERTY(PROP_NORMALS, QVector<glm::vec3>, setNormals);
|
||||
READ_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, QVector<float>, setStrokeWidths);
|
||||
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
|
||||
// TODO: eventually only include properties changed since the params.lastViewFrustumSent time
|
||||
EntityPropertyFlags PolyLineEntityItem::getEntityProperties(EncodeBitstreamParams& params) const {
|
||||
EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params);
|
||||
requestedProperties += PROP_COLOR;
|
||||
requestedProperties += PROP_LINE_WIDTH;
|
||||
requestedProperties += PROP_LINE_POINTS;
|
||||
requestedProperties += PROP_NORMALS;
|
||||
requestedProperties += PROP_STROKE_WIDTHS;
|
||||
return requestedProperties;
|
||||
}
|
||||
|
||||
void PolyLineEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
|
||||
EntityTreeElementExtraEncodeData* modelTreeElementExtraEncodeData,
|
||||
EntityPropertyFlags& requestedProperties,
|
||||
EntityPropertyFlags& propertyFlags,
|
||||
EntityPropertyFlags& propertiesDidntFit,
|
||||
int& propertyCount,
|
||||
OctreeElement::AppendState& appendState) const {
|
||||
|
||||
QWriteLocker lock(&_quadReadWriteLock);
|
||||
bool successPropertyFits = true;
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_COLOR, getColor());
|
||||
APPEND_ENTITY_PROPERTY(PROP_LINE_WIDTH, getLineWidth());
|
||||
APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, getLinePoints());
|
||||
APPEND_ENTITY_PROPERTY(PROP_NORMALS, getNormals());
|
||||
APPEND_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, getStrokeWidths());
|
||||
}
|
||||
|
||||
void PolyLineEntityItem::debugDump() const {
|
||||
quint64 now = usecTimestampNow();
|
||||
qCDebug(entities) << " QUAD EntityItem id:" << getEntityItemID() << "---------------------------------------------";
|
||||
qCDebug(entities) << " color:" << _color[0] << "," << _color[1] << "," << _color[2];
|
||||
qCDebug(entities) << " position:" << debugTreeVector(getPosition());
|
||||
qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions());
|
||||
qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now);
|
||||
}
|
||||
|
94
libraries/entities/src/PolyLineEntityItem.h
Normal file
94
libraries/entities/src/PolyLineEntityItem.h
Normal file
|
@ -0,0 +1,94 @@
|
|||
//
|
||||
// PolyLineEntityItem.h
|
||||
// libraries/entities/src
|
||||
//
|
||||
// Created by Eric Levin on 8/3/15.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_PolyLineEntityItem_h
|
||||
#define hifi_PolyLineEntityItem_h
|
||||
|
||||
#include "EntityItem.h"
|
||||
|
||||
class PolyLineEntityItem : public EntityItem {
|
||||
public:
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
|
||||
PolyLineEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
||||
|
||||
ALLOW_INSTANTIATION // This class can be instantiated
|
||||
|
||||
// methods for getting/setting all properties of an entity
|
||||
virtual EntityItemProperties getProperties() const;
|
||||
virtual bool setProperties(const EntityItemProperties& properties);
|
||||
|
||||
// TODO: eventually only include properties changed since the params.lastViewFrustumSent time
|
||||
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const;
|
||||
|
||||
virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
|
||||
EntityTreeElementExtraEncodeData* modelTreeElementExtraEncodeData,
|
||||
EntityPropertyFlags& requestedProperties,
|
||||
EntityPropertyFlags& propertyFlags,
|
||||
EntityPropertyFlags& propertiesDidntFit,
|
||||
int& propertyCount,
|
||||
OctreeElement::AppendState& appendState) const;
|
||||
|
||||
virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
||||
ReadBitstreamToTreeParams& args,
|
||||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData);
|
||||
|
||||
const rgbColor& getColor() const { return _color; }
|
||||
xColor getXColor() const { xColor color = { _color[RED_INDEX], _color[GREEN_INDEX], _color[BLUE_INDEX] }; return color; }
|
||||
|
||||
void setColor(const rgbColor& value) {
|
||||
memcpy(_color, value, sizeof(_color));
|
||||
}
|
||||
void setColor(const xColor& value) {
|
||||
|
||||
_color[RED_INDEX] = value.red;
|
||||
_color[GREEN_INDEX] = value.green;
|
||||
_color[BLUE_INDEX] = value.blue;
|
||||
}
|
||||
|
||||
void setLineWidth(float lineWidth){ _lineWidth = lineWidth; }
|
||||
float getLineWidth() const{ return _lineWidth; }
|
||||
|
||||
bool setLinePoints(const QVector<glm::vec3>& points);
|
||||
bool appendPoint(const glm::vec3& point);
|
||||
const QVector<glm::vec3>& getLinePoints() const{ return _points; }
|
||||
|
||||
bool setNormals(const QVector<glm::vec3>& normals);
|
||||
const QVector<glm::vec3>& getNormals() const{ return _normals; }
|
||||
|
||||
bool setStrokeWidths(const QVector<float>& strokeWidths);
|
||||
const QVector<float>& getStrokeWidths() const{ return _strokeWidths; }
|
||||
|
||||
|
||||
virtual ShapeType getShapeType() const { return SHAPE_TYPE_LINE; }
|
||||
|
||||
// never have a ray intersection pick a PolyLineEntityItem.
|
||||
virtual bool supportsDetailedRayIntersection() const { return true; }
|
||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face,
|
||||
void** intersectedObject, bool precisionPicking) const { return false; }
|
||||
|
||||
virtual void debugDump() const;
|
||||
static const float DEFAULT_LINE_WIDTH;
|
||||
static const int MAX_POINTS_PER_LINE;
|
||||
|
||||
protected:
|
||||
rgbColor _color;
|
||||
float _lineWidth;
|
||||
bool _pointsChanged;
|
||||
QVector<glm::vec3> _points;
|
||||
QVector<glm::vec3> _vertices;
|
||||
QVector<glm::vec3> _normals;
|
||||
QVector<float> _strokeWidths;
|
||||
mutable QReadWriteLock _quadReadWriteLock;
|
||||
};
|
||||
|
||||
#endif // hifi_PolyLineEntityItem_h
|
|
@ -67,7 +67,7 @@ PacketVersion versionForPacketType(PacketType::Value packetType) {
|
|||
case EntityAdd:
|
||||
case EntityEdit:
|
||||
case EntityData:
|
||||
return VERSION_POLYVOX_TEXTURES;
|
||||
return VERSION_ENTITIES_POLYLINE;
|
||||
default:
|
||||
return 11;
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ namespace PacketType {
|
|||
EntityErase,
|
||||
EntityEdit,
|
||||
DomainServerConnectionToken
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
const int NUM_BYTES_MD5_HASH = 16;
|
||||
|
@ -141,5 +141,6 @@ const PacketVersion VERSION_ENTITIES_SCRIPT_TIMESTAMP_FIX = 32;
|
|||
const PacketVersion VERSION_ENTITIES_HAVE_SIMULATION_OWNER_AND_ACTIONS_OVER_WIRE = 33;
|
||||
const PacketVersion VERSION_ENTITIES_NEW_PROTOCOL_LAYER = 35;
|
||||
const PacketVersion VERSION_POLYVOX_TEXTURES = 36;
|
||||
const PacketVersion VERSION_ENTITIES_POLYLINE = 37;
|
||||
|
||||
#endif // hifi_PacketHeaders_h
|
||||
#endif // hifi_PacketHeaders_h
|
|
@ -394,6 +394,19 @@ bool OctreePacketData::appendValue(const QVector<glm::vec3>& value) {
|
|||
return success;
|
||||
}
|
||||
|
||||
bool OctreePacketData::appendValue(const QVector<float>& value) {
|
||||
uint16_t qVecSize = value.size();
|
||||
bool success = appendValue(qVecSize);
|
||||
if (success) {
|
||||
success = append((const unsigned char*)value.constData(), qVecSize * sizeof(float));
|
||||
if (success) {
|
||||
_bytesOfValues += qVecSize * sizeof(float);
|
||||
_totalBytesOfValues += qVecSize * sizeof(float);
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
bool OctreePacketData::appendValue(const glm::quat& value) {
|
||||
const size_t VALUES_PER_QUAT = 4;
|
||||
const size_t PACKED_QUAT_SIZE = sizeof(uint16_t) * VALUES_PER_QUAT;
|
||||
|
@ -609,6 +622,16 @@ int OctreePacketData::unpackDataFromBytes(const unsigned char *dataBytes, QVecto
|
|||
memcpy(result.data(), dataBytes, length * sizeof(glm::vec3));
|
||||
return sizeof(uint16_t) + length * sizeof(glm::vec3);
|
||||
}
|
||||
|
||||
int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, QVector<float>& result) {
|
||||
uint16_t length;
|
||||
memcpy(&length, dataBytes, sizeof(uint16_t));
|
||||
dataBytes += sizeof(length);
|
||||
result.resize(length);
|
||||
memcpy(result.data(), dataBytes, length * sizeof(float));
|
||||
return sizeof(uint16_t) + length * sizeof(float);
|
||||
}
|
||||
|
||||
int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, QByteArray& result) {
|
||||
uint16_t length;
|
||||
memcpy(&length, dataBytes, sizeof(length));
|
||||
|
|
|
@ -165,6 +165,9 @@ public:
|
|||
|
||||
//appends a QVector of vec3's to the end of the stream, may fail if new data stream is too long to fit in packet
|
||||
bool appendValue(const QVector<glm::vec3>& value);
|
||||
|
||||
//appends a QVector of floats to the end of the stream, may fail if new data stream is too long to fit in packet
|
||||
bool appendValue(const QVector<float>& value);
|
||||
|
||||
/// appends a packed quat to the end of the stream, may fail if new data stream is too long to fit in packet
|
||||
bool appendValue(const glm::quat& value);
|
||||
|
@ -245,6 +248,7 @@ public:
|
|||
static int unpackDataFromBytes(const unsigned char* dataBytes, QUuid& result);
|
||||
static int unpackDataFromBytes(const unsigned char* dataBytes, xColor& result);
|
||||
static int unpackDataFromBytes(const unsigned char* dataBytes, QVector<glm::vec3>& result);
|
||||
static int unpackDataFromBytes(const unsigned char* dataBytes, QVector<float>& result);
|
||||
static int unpackDataFromBytes(const unsigned char* dataBytes, QByteArray& result);
|
||||
|
||||
private:
|
||||
|
|
|
@ -139,6 +139,8 @@ void DeferredLightingEffect::init(AbstractViewStateInterface* viewState) {
|
|||
lp->setAmbientSpherePreset(gpu::SphericalHarmonics::Preset(_ambientLightMode % gpu::SphericalHarmonics::NUM_PRESET));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void DeferredLightingEffect::bindSimpleProgram(gpu::Batch& batch, bool textured, bool culled,
|
||||
bool emmisive, bool depthBias) {
|
||||
SimpleProgramKey config{textured, culled, emmisive, depthBias};
|
||||
|
|
|
@ -77,6 +77,7 @@ public:
|
|||
void setGlobalAtmosphere(const model::AtmospherePointer& atmosphere) { _atmosphere = atmosphere; }
|
||||
|
||||
void setGlobalSkybox(const model::SkyboxPointer& skybox);
|
||||
|
||||
private:
|
||||
DeferredLightingEffect() {}
|
||||
virtual ~DeferredLightingEffect() { }
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "AbstractViewStateInterface.h"
|
||||
#include "HitEffect.h"
|
||||
|
||||
#include "TextureCache.h"
|
||||
#include "DependencyManager.h"
|
||||
#include "ViewFrustum.h"
|
||||
|
@ -43,6 +44,7 @@ const gpu::PipelinePointer& HitEffect::getHitEffectPipeline() {
|
|||
gpu::Shader::BindingSet slotBindings;
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
|
||||
state->setDepthTest(false, false, gpu::LESS_EQUAL);
|
||||
|
@ -50,7 +52,7 @@ const gpu::PipelinePointer& HitEffect::getHitEffectPipeline() {
|
|||
// Blend on transparent
|
||||
state->setBlendFunction(true,
|
||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA);
|
||||
|
||||
|
||||
// Good to go add the brand new pipeline
|
||||
_hitEffectPipeline.reset(gpu::Pipeline::create(program, state));
|
||||
}
|
||||
|
@ -77,9 +79,6 @@ void HitEffect::run(const render::SceneContextPointer& sceneContext, const rende
|
|||
glm::vec2 bottomLeft(-1.0f, -1.0f);
|
||||
glm::vec2 topRight(1.0f, 1.0f);
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, color);
|
||||
|
||||
|
||||
// Ready to render
|
||||
args->_context->render((batch));
|
||||
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ public:
|
|||
const gpu::PipelinePointer& getHitEffectPipeline();
|
||||
|
||||
private:
|
||||
|
||||
gpu::PipelinePointer _hitEffectPipeline;
|
||||
};
|
||||
|
||||
|
|
|
@ -106,6 +106,7 @@ RenderDeferredTask::RenderDeferredTask() : Task() {
|
|||
_drawStatusJobIndex = _jobs.size() - 1;
|
||||
|
||||
_jobs.push_back(Job(new DrawOverlay3D::JobModel("DrawOverlay3D")));
|
||||
|
||||
_jobs.push_back(Job(new HitEffect::JobModel("HitEffect")));
|
||||
_jobs.back().setEnabled(false);
|
||||
_drawHitEffectJobIndex = _jobs.size() -1;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
|
||||
// hit_effect.frag
|
||||
// fragment shader
|
||||
//
|
||||
|
@ -12,6 +13,7 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
|
||||
in vec2 varQuadPosition;
|
||||
|
|
|
@ -33,6 +33,7 @@ void registerMetaTypes(QScriptEngine* engine) {
|
|||
qScriptRegisterMetaType(engine, vec4toScriptValue, vec4FromScriptValue);
|
||||
qScriptRegisterMetaType(engine, vec3toScriptValue, vec3FromScriptValue);
|
||||
qScriptRegisterMetaType(engine, qVectorVec3ToScriptValue, qVectorVec3FromScriptValue);
|
||||
qScriptRegisterMetaType(engine, qVectorFloatToScriptValue, qVectorFloatFromScriptValue);
|
||||
qScriptRegisterMetaType(engine, vec2toScriptValue, vec2FromScriptValue);
|
||||
qScriptRegisterMetaType(engine, quatToScriptValue, quatFromScriptValue);
|
||||
qScriptRegisterMetaType(engine, qRectToScriptValue, qRectFromScriptValue);
|
||||
|
@ -43,6 +44,7 @@ void registerMetaTypes(QScriptEngine* engine) {
|
|||
qScriptRegisterMetaType(engine, collisionToScriptValue, collisionFromScriptValue);
|
||||
qScriptRegisterMetaType(engine, quuidToScriptValue, quuidFromScriptValue);
|
||||
qScriptRegisterMetaType(engine, qSizeFToScriptValue, qSizeFFromScriptValue);
|
||||
|
||||
}
|
||||
|
||||
QScriptValue vec4toScriptValue(QScriptEngine* engine, const glm::vec4& vec4) {
|
||||
|
@ -79,7 +81,7 @@ void vec3FromScriptValue(const QScriptValue &object, glm::vec3 &vec3) {
|
|||
vec3.z = object.property("z").toVariant().toFloat();
|
||||
}
|
||||
|
||||
QScriptValue qVectorVec3ToScriptValue(QScriptEngine* engine, const QVector<glm::vec3>& vector){
|
||||
QScriptValue qVectorVec3ToScriptValue(QScriptEngine* engine, const QVector<glm::vec3>& vector) {
|
||||
QScriptValue array = engine->newArray();
|
||||
for (int i = 0; i < vector.size(); i++) {
|
||||
array.setProperty(i, vec3toScriptValue(engine, vector.at(i)));
|
||||
|
@ -87,6 +89,39 @@ QScriptValue qVectorVec3ToScriptValue(QScriptEngine* engine, const QVector<glm::
|
|||
return array;
|
||||
}
|
||||
|
||||
QVector<float> qVectorFloatFromScriptValue(const QScriptValue& array) {
|
||||
if(!array.isArray()) {
|
||||
return QVector<float>();
|
||||
}
|
||||
QVector<float> newVector;
|
||||
int length = array.property("length").toInteger();
|
||||
newVector.reserve(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
if(array.property(i).isNumber()) {
|
||||
newVector << array.property(i).toNumber();
|
||||
}
|
||||
}
|
||||
|
||||
return newVector;
|
||||
}
|
||||
|
||||
QScriptValue qVectorFloatToScriptValue(QScriptEngine* engine, const QVector<float>& vector) {
|
||||
QScriptValue array = engine->newArray();
|
||||
for (int i = 0; i < vector.size(); i++) {
|
||||
float num = vector.at(i);
|
||||
array.setProperty(i, QScriptValue(num));
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
void qVectorFloatFromScriptValue(const QScriptValue& array, QVector<float>& vector) {
|
||||
int length = array.property("length").toInteger();
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
vector << array.property(i).toVariant().toFloat();
|
||||
}
|
||||
}
|
||||
//
|
||||
QVector<glm::vec3> qVectorVec3FromScriptValue(const QScriptValue& array){
|
||||
QVector<glm::vec3> newVector;
|
||||
int length = array.property("length").toInteger();
|
||||
|
|
|
@ -29,6 +29,7 @@ Q_DECLARE_METATYPE(glm::vec2)
|
|||
Q_DECLARE_METATYPE(glm::quat)
|
||||
Q_DECLARE_METATYPE(xColor)
|
||||
Q_DECLARE_METATYPE(QVector<glm::vec3>)
|
||||
Q_DECLARE_METATYPE(QVector<float>)
|
||||
|
||||
void registerMetaTypes(QScriptEngine* engine);
|
||||
|
||||
|
@ -60,6 +61,10 @@ QScriptValue qVectorVec3ToScriptValue(QScriptEngine* engine, const QVector<glm::
|
|||
void qVectorVec3FromScriptValue(const QScriptValue& array, QVector<glm::vec3>& vector);
|
||||
QVector<glm::vec3> qVectorVec3FromScriptValue( const QScriptValue& array);
|
||||
|
||||
QScriptValue qVectorFloatToScriptValue(QScriptEngine* engine, const QVector<float>& vector);
|
||||
void qVectorFloatFromScriptValue(const QScriptValue& array, QVector<float>& vector);
|
||||
QVector<float> qVectorFloatFromScriptValue(const QScriptValue& array);
|
||||
|
||||
class PickRay {
|
||||
public:
|
||||
PickRay() : origin(0.0f), direction(0.0f) { }
|
||||
|
|
|
@ -109,6 +109,8 @@
|
|||
#include "sdf_text3D_vert.h"
|
||||
#include "sdf_text3D_frag.h"
|
||||
|
||||
#include "paintStroke_vert.h"
|
||||
#include "paintStroke_frag.h"
|
||||
|
||||
class RateCounter {
|
||||
std::vector<float> times;
|
||||
|
@ -324,6 +326,8 @@ void QTestWindow::draw() {
|
|||
testShaderBuild(SkyFromAtmosphere_vert, SkyFromAtmosphere_frag);
|
||||
|
||||
testShaderBuild(Skybox_vert, Skybox_frag);
|
||||
|
||||
testShaderBuild(paintStroke_vert,paintStroke_frag);
|
||||
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue