mirror of
https://github.com/lubosz/overte.git
synced 2025-08-07 19:41:20 +02:00
Merge pull request #2745 from ZappoMan/rayintersection
added support for returning accuracy of ray intersections and other octree tests that can fail due to getting lock
This commit is contained in:
commit
a934ffb1d7
9 changed files with 112 additions and 29 deletions
|
@ -19,6 +19,12 @@ function mouseMoveEvent(event) {
|
||||||
print("computePickRay direction=" + pickRay.direction.x + ", " + pickRay.direction.y + ", " + pickRay.direction.z);
|
print("computePickRay direction=" + pickRay.direction.x + ", " + pickRay.direction.y + ", " + pickRay.direction.z);
|
||||||
var pickRay = Camera.computePickRay(event.x, event.y);
|
var pickRay = Camera.computePickRay(event.x, event.y);
|
||||||
var intersection = Voxels.findRayIntersection(pickRay);
|
var intersection = Voxels.findRayIntersection(pickRay);
|
||||||
|
if (!intersection.accurate) {
|
||||||
|
print(">>> NOTE: intersection not accurate. will try calling Voxels.findRayIntersectionBlocking()");
|
||||||
|
intersection = Voxels.findRayIntersectionBlocking(pickRay);
|
||||||
|
print(">>> AFTER BLOCKING CALL intersection.accurate=" + intersection.accurate);
|
||||||
|
}
|
||||||
|
|
||||||
if (intersection.intersects) {
|
if (intersection.intersects) {
|
||||||
print("intersection voxel.red/green/blue=" + intersection.voxel.red + ", "
|
print("intersection voxel.red/green/blue=" + intersection.voxel.red + ", "
|
||||||
+ intersection.voxel.green + ", " + intersection.voxel.blue);
|
+ intersection.voxel.green + ", " + intersection.voxel.blue);
|
||||||
|
|
|
@ -594,8 +594,9 @@ bool findRayIntersectionOp(OctreeElement* node, void* extraData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Octree::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
bool Octree::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
OctreeElement*& node, float& distance, BoxFace& face, Octree::lockType lockType) {
|
OctreeElement*& node, float& distance, BoxFace& face,
|
||||||
RayArgs args = { origin / (float)(TREE_SCALE), direction, node, distance, face };
|
Octree::lockType lockType, bool* accurateResult) {
|
||||||
|
RayArgs args = { origin / (float)(TREE_SCALE), direction, node, distance, face, false};
|
||||||
|
|
||||||
bool gotLock = false;
|
bool gotLock = false;
|
||||||
if (lockType == Octree::Lock) {
|
if (lockType == Octree::Lock) {
|
||||||
|
@ -604,6 +605,9 @@ bool Octree::findRayIntersection(const glm::vec3& origin, const glm::vec3& direc
|
||||||
} else if (lockType == Octree::TryLock) {
|
} else if (lockType == Octree::TryLock) {
|
||||||
gotLock = tryLockForRead();
|
gotLock = tryLockForRead();
|
||||||
if (!gotLock) {
|
if (!gotLock) {
|
||||||
|
if (accurateResult) {
|
||||||
|
*accurateResult = false; // if user asked to accuracy or result, let them know this is inaccurate
|
||||||
|
}
|
||||||
return args.found; // if we wanted to tryLock, and we couldn't then just bail...
|
return args.found; // if we wanted to tryLock, and we couldn't then just bail...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -614,6 +618,9 @@ bool Octree::findRayIntersection(const glm::vec3& origin, const glm::vec3& direc
|
||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (accurateResult) {
|
||||||
|
*accurateResult = true; // if user asked to accuracy or result, let them know this is accurate
|
||||||
|
}
|
||||||
return args.found;
|
return args.found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -640,7 +647,8 @@ bool findSpherePenetrationOp(OctreeElement* element, void* extraData) {
|
||||||
if (element->hasContent()) {
|
if (element->hasContent()) {
|
||||||
glm::vec3 elementPenetration;
|
glm::vec3 elementPenetration;
|
||||||
if (element->findSpherePenetration(args->center, args->radius, elementPenetration, &args->penetratedObject)) {
|
if (element->findSpherePenetration(args->center, args->radius, elementPenetration, &args->penetratedObject)) {
|
||||||
// NOTE: it is possible for this penetration accumulation algorithm to produce a final penetration vector with zero length.
|
// NOTE: it is possible for this penetration accumulation algorithm to produce a
|
||||||
|
// final penetration vector with zero length.
|
||||||
args->penetration = addPenetrations(args->penetration, elementPenetration * (float)(TREE_SCALE));
|
args->penetration = addPenetrations(args->penetration, elementPenetration * (float)(TREE_SCALE));
|
||||||
args->found = true;
|
args->found = true;
|
||||||
}
|
}
|
||||||
|
@ -649,7 +657,7 @@ bool findSpherePenetrationOp(OctreeElement* element, void* extraData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Octree::findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration,
|
bool Octree::findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration,
|
||||||
void** penetratedObject, Octree::lockType lockType) {
|
void** penetratedObject, Octree::lockType lockType, bool* accurateResult) {
|
||||||
|
|
||||||
SphereArgs args = {
|
SphereArgs args = {
|
||||||
center / (float)(TREE_SCALE),
|
center / (float)(TREE_SCALE),
|
||||||
|
@ -666,6 +674,9 @@ bool Octree::findSpherePenetration(const glm::vec3& center, float radius, glm::v
|
||||||
} else if (lockType == Octree::TryLock) {
|
} else if (lockType == Octree::TryLock) {
|
||||||
gotLock = tryLockForRead();
|
gotLock = tryLockForRead();
|
||||||
if (!gotLock) {
|
if (!gotLock) {
|
||||||
|
if (accurateResult) {
|
||||||
|
*accurateResult = false; // if user asked to accuracy or result, let them know this is inaccurate
|
||||||
|
}
|
||||||
return args.found; // if we wanted to tryLock, and we couldn't then just bail...
|
return args.found; // if we wanted to tryLock, and we couldn't then just bail...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -679,6 +690,9 @@ bool Octree::findSpherePenetration(const glm::vec3& center, float radius, glm::v
|
||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (accurateResult) {
|
||||||
|
*accurateResult = true; // if user asked to accuracy or result, let them know this is accurate
|
||||||
|
}
|
||||||
return args.found;
|
return args.found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -741,7 +755,7 @@ bool findShapeCollisionsOp(OctreeElement* node, void* extraData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Octree::findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius,
|
bool Octree::findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius,
|
||||||
glm::vec3& penetration, Octree::lockType lockType) {
|
glm::vec3& penetration, Octree::lockType lockType, bool* accurateResult) {
|
||||||
|
|
||||||
CapsuleArgs args = {
|
CapsuleArgs args = {
|
||||||
start / (float)(TREE_SCALE),
|
start / (float)(TREE_SCALE),
|
||||||
|
@ -758,6 +772,9 @@ bool Octree::findCapsulePenetration(const glm::vec3& start, const glm::vec3& end
|
||||||
} else if (lockType == Octree::TryLock) {
|
} else if (lockType == Octree::TryLock) {
|
||||||
gotLock = tryLockForRead();
|
gotLock = tryLockForRead();
|
||||||
if (!gotLock) {
|
if (!gotLock) {
|
||||||
|
if (accurateResult) {
|
||||||
|
*accurateResult = false; // if user asked to accuracy or result, let them know this is inaccurate
|
||||||
|
}
|
||||||
return args.found; // if we wanted to tryLock, and we couldn't then just bail...
|
return args.found; // if we wanted to tryLock, and we couldn't then just bail...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -767,10 +784,15 @@ bool Octree::findCapsulePenetration(const glm::vec3& start, const glm::vec3& end
|
||||||
if (gotLock) {
|
if (gotLock) {
|
||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (accurateResult) {
|
||||||
|
*accurateResult = true; // if user asked to accuracy or result, let them know this is accurate
|
||||||
|
}
|
||||||
return args.found;
|
return args.found;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Octree::findShapeCollisions(const Shape* shape, CollisionList& collisions, Octree::lockType lockType) {
|
bool Octree::findShapeCollisions(const Shape* shape, CollisionList& collisions,
|
||||||
|
Octree::lockType lockType, bool* accurateResult) {
|
||||||
|
|
||||||
ShapeArgs args = { shape, collisions, false };
|
ShapeArgs args = { shape, collisions, false };
|
||||||
|
|
||||||
|
@ -781,6 +803,9 @@ bool Octree::findShapeCollisions(const Shape* shape, CollisionList& collisions,
|
||||||
} else if (lockType == Octree::TryLock) {
|
} else if (lockType == Octree::TryLock) {
|
||||||
gotLock = tryLockForRead();
|
gotLock = tryLockForRead();
|
||||||
if (!gotLock) {
|
if (!gotLock) {
|
||||||
|
if (accurateResult) {
|
||||||
|
*accurateResult = false; // if user asked to accuracy or result, let them know this is inaccurate
|
||||||
|
}
|
||||||
return args.found; // if we wanted to tryLock, and we couldn't then just bail...
|
return args.found; // if we wanted to tryLock, and we couldn't then just bail...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -790,6 +815,10 @@ bool Octree::findShapeCollisions(const Shape* shape, CollisionList& collisions,
|
||||||
if (gotLock) {
|
if (gotLock) {
|
||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (accurateResult) {
|
||||||
|
*accurateResult = true; // if user asked to accuracy or result, let them know this is accurate
|
||||||
|
}
|
||||||
return args.found;
|
return args.found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -816,7 +845,7 @@ bool getElementEnclosingOperation(OctreeElement* element, void* extraData) {
|
||||||
return true; // keep looking
|
return true; // keep looking
|
||||||
}
|
}
|
||||||
|
|
||||||
OctreeElement* Octree::getElementEnclosingPoint(const glm::vec3& point, Octree::lockType lockType) {
|
OctreeElement* Octree::getElementEnclosingPoint(const glm::vec3& point, Octree::lockType lockType, bool* accurateResult) {
|
||||||
GetElementEnclosingArgs args;
|
GetElementEnclosingArgs args;
|
||||||
args.point = point;
|
args.point = point;
|
||||||
args.element = NULL;
|
args.element = NULL;
|
||||||
|
@ -828,6 +857,9 @@ OctreeElement* Octree::getElementEnclosingPoint(const glm::vec3& point, Octree::
|
||||||
} else if (lockType == Octree::TryLock) {
|
} else if (lockType == Octree::TryLock) {
|
||||||
gotLock = tryLockForRead();
|
gotLock = tryLockForRead();
|
||||||
if (!gotLock) {
|
if (!gotLock) {
|
||||||
|
if (accurateResult) {
|
||||||
|
*accurateResult = false; // if user asked to accuracy or result, let them know this is inaccurate
|
||||||
|
}
|
||||||
return args.element; // if we wanted to tryLock, and we couldn't then just bail...
|
return args.element; // if we wanted to tryLock, and we couldn't then just bail...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -838,6 +870,9 @@ OctreeElement* Octree::getElementEnclosingPoint(const glm::vec3& point, Octree::
|
||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (accurateResult) {
|
||||||
|
*accurateResult = false; // if user asked to accuracy or result, let them know this is inaccurate
|
||||||
|
}
|
||||||
return args.element;
|
return args.element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -249,17 +249,20 @@ public:
|
||||||
} lockType;
|
} lockType;
|
||||||
|
|
||||||
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
OctreeElement*& node, float& distance, BoxFace& face, Octree::lockType lockType = Octree::TryLock);
|
OctreeElement*& node, float& distance, BoxFace& face,
|
||||||
|
Octree::lockType lockType = Octree::TryLock, bool* accurateResult = NULL);
|
||||||
|
|
||||||
bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration,
|
bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration, void** penetratedObject = NULL,
|
||||||
void** penetratedObject = NULL, Octree::lockType lockType = Octree::TryLock);
|
Octree::lockType lockType = Octree::TryLock, bool* accurateResult = NULL);
|
||||||
|
|
||||||
bool findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius,
|
bool findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration,
|
||||||
glm::vec3& penetration, Octree::lockType lockType = Octree::TryLock);
|
Octree::lockType lockType = Octree::TryLock, bool* accurateResult = NULL);
|
||||||
|
|
||||||
bool findShapeCollisions(const Shape* shape, CollisionList& collisions, Octree::lockType = Octree::TryLock);
|
bool findShapeCollisions(const Shape* shape, CollisionList& collisions,
|
||||||
|
Octree::lockType = Octree::TryLock, bool* accurateResult = NULL);
|
||||||
|
|
||||||
OctreeElement* getElementEnclosingPoint(const glm::vec3& point, Octree::lockType lockType = Octree::TryLock);
|
OctreeElement* getElementEnclosingPoint(const glm::vec3& point,
|
||||||
|
Octree::lockType lockType = Octree::TryLock, bool* accurateResult = NULL);
|
||||||
|
|
||||||
// Note: this assumes the fileFormat is the HIO individual voxels code files
|
// Note: this assumes the fileFormat is the HIO individual voxels code files
|
||||||
void loadOctreeFile(const char* fileName, bool wantColorRandomizer);
|
void loadOctreeFile(const char* fileName, bool wantColorRandomizer);
|
||||||
|
|
|
@ -119,10 +119,19 @@ void LocalVoxels::pasteFrom(float x, float y, float z, float scale, const QStrin
|
||||||
}
|
}
|
||||||
|
|
||||||
RayToVoxelIntersectionResult LocalVoxels::findRayIntersection(const PickRay& ray) {
|
RayToVoxelIntersectionResult LocalVoxels::findRayIntersection(const PickRay& ray) {
|
||||||
|
return findRayIntersectionWorker(ray, Octree::TryLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
RayToVoxelIntersectionResult LocalVoxels::findRayIntersectionBlocking(const PickRay& ray) {
|
||||||
|
return findRayIntersectionWorker(ray, Octree::Lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
RayToVoxelIntersectionResult LocalVoxels::findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType) {
|
||||||
RayToVoxelIntersectionResult result;
|
RayToVoxelIntersectionResult result;
|
||||||
if (_tree) {
|
if (_tree) {
|
||||||
OctreeElement* element;
|
OctreeElement* element;
|
||||||
result.intersects = _tree->findRayIntersection(ray.origin, ray.direction, element, result.distance, result.face);
|
result.intersects = _tree->findRayIntersection(ray.origin, ray.direction, element, result.distance, result.face,
|
||||||
|
lockType, &result.accurate);
|
||||||
if (result.intersects) {
|
if (result.intersects) {
|
||||||
VoxelTreeElement* voxel = (VoxelTreeElement*)element;
|
VoxelTreeElement* voxel = (VoxelTreeElement*)element;
|
||||||
result.voxel.x = voxel->getCorner().x;
|
result.voxel.x = voxel->getCorner().x;
|
||||||
|
|
|
@ -76,13 +76,22 @@ public:
|
||||||
/// \param source LocalVoxels' source tree
|
/// \param source LocalVoxels' source tree
|
||||||
Q_INVOKABLE void pasteFrom(float x, float y, float z, float scale, const QString source);
|
Q_INVOKABLE void pasteFrom(float x, float y, float z, float scale, const QString source);
|
||||||
|
|
||||||
/// If the scripting context has visible voxels, this will determine a ray intersection
|
/// If the scripting context has visible voxels, this will determine a ray intersection, the results
|
||||||
|
/// may be inaccurate if the engine is unable to access the visible voxels, in which case result.accurate
|
||||||
|
/// will be false.
|
||||||
Q_INVOKABLE RayToVoxelIntersectionResult findRayIntersection(const PickRay& ray);
|
Q_INVOKABLE RayToVoxelIntersectionResult findRayIntersection(const PickRay& ray);
|
||||||
|
|
||||||
|
/// If the scripting context has visible voxels, this will determine a ray intersection, and will block in
|
||||||
|
/// order to return an accurate result
|
||||||
|
Q_INVOKABLE RayToVoxelIntersectionResult findRayIntersectionBlocking(const PickRay& ray);
|
||||||
|
|
||||||
/// returns a voxel space axis aligned vector for the face, useful in doing voxel math
|
/// returns a voxel space axis aligned vector for the face, useful in doing voxel math
|
||||||
Q_INVOKABLE glm::vec3 getFaceVector(const QString& face);
|
Q_INVOKABLE glm::vec3 getFaceVector(const QString& face);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/// actually does the work of finding the ray intersection, can be called in locking mode or tryLock mode
|
||||||
|
RayToVoxelIntersectionResult findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType);
|
||||||
|
|
||||||
QString _name;
|
QString _name;
|
||||||
StrongVoxelTreePointer _tree;
|
StrongVoxelTreePointer _tree;
|
||||||
};
|
};
|
||||||
|
|
|
@ -41,6 +41,7 @@ void voxelDetailFromScriptValue(const QScriptValue &object, VoxelDetail& voxelDe
|
||||||
|
|
||||||
RayToVoxelIntersectionResult::RayToVoxelIntersectionResult() :
|
RayToVoxelIntersectionResult::RayToVoxelIntersectionResult() :
|
||||||
intersects(false),
|
intersects(false),
|
||||||
|
accurate(true), // assume it's accurate
|
||||||
voxel(),
|
voxel(),
|
||||||
distance(0),
|
distance(0),
|
||||||
face()
|
face()
|
||||||
|
@ -50,6 +51,7 @@ RayToVoxelIntersectionResult::RayToVoxelIntersectionResult() :
|
||||||
QScriptValue rayToVoxelIntersectionResultToScriptValue(QScriptEngine* engine, const RayToVoxelIntersectionResult& value) {
|
QScriptValue rayToVoxelIntersectionResultToScriptValue(QScriptEngine* engine, const RayToVoxelIntersectionResult& value) {
|
||||||
QScriptValue obj = engine->newObject();
|
QScriptValue obj = engine->newObject();
|
||||||
obj.setProperty("intersects", value.intersects);
|
obj.setProperty("intersects", value.intersects);
|
||||||
|
obj.setProperty("accurate", value.accurate);
|
||||||
QScriptValue voxelValue = voxelDetailToScriptValue(engine, value.voxel);
|
QScriptValue voxelValue = voxelDetailToScriptValue(engine, value.voxel);
|
||||||
obj.setProperty("voxel", voxelValue);
|
obj.setProperty("voxel", voxelValue);
|
||||||
obj.setProperty("distance", value.distance);
|
obj.setProperty("distance", value.distance);
|
||||||
|
@ -88,6 +90,7 @@ QScriptValue rayToVoxelIntersectionResultToScriptValue(QScriptEngine* engine, co
|
||||||
|
|
||||||
void rayToVoxelIntersectionResultFromScriptValue(const QScriptValue& object, RayToVoxelIntersectionResult& value) {
|
void rayToVoxelIntersectionResultFromScriptValue(const QScriptValue& object, RayToVoxelIntersectionResult& value) {
|
||||||
value.intersects = object.property("intersects").toVariant().toBool();
|
value.intersects = object.property("intersects").toVariant().toBool();
|
||||||
|
value.accurate = object.property("accurate").toVariant().toBool();
|
||||||
QScriptValue voxelValue = object.property("voxel");
|
QScriptValue voxelValue = object.property("voxel");
|
||||||
if (voxelValue.isValid()) {
|
if (voxelValue.isValid()) {
|
||||||
voxelDetailFromScriptValue(voxelValue, value.voxel);
|
voxelDetailFromScriptValue(voxelValue, value.voxel);
|
||||||
|
|
|
@ -39,6 +39,7 @@ class RayToVoxelIntersectionResult {
|
||||||
public:
|
public:
|
||||||
RayToVoxelIntersectionResult();
|
RayToVoxelIntersectionResult();
|
||||||
bool intersects;
|
bool intersects;
|
||||||
|
bool accurate;
|
||||||
VoxelDetail voxel;
|
VoxelDetail voxel;
|
||||||
float distance;
|
float distance;
|
||||||
BoxFace face;
|
BoxFace face;
|
||||||
|
|
|
@ -122,12 +122,21 @@ void VoxelsScriptingInterface::eraseVoxel(float x, float y, float z, float scale
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RayToVoxelIntersectionResult VoxelsScriptingInterface::findRayIntersection(const PickRay& ray) {
|
RayToVoxelIntersectionResult VoxelsScriptingInterface::findRayIntersection(const PickRay& ray) {
|
||||||
|
return findRayIntersectionWorker(ray, Octree::TryLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
RayToVoxelIntersectionResult VoxelsScriptingInterface::findRayIntersectionBlocking(const PickRay& ray) {
|
||||||
|
return findRayIntersectionWorker(ray, Octree::Lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
RayToVoxelIntersectionResult VoxelsScriptingInterface::findRayIntersectionWorker(const PickRay& ray,
|
||||||
|
Octree::lockType lockType) {
|
||||||
RayToVoxelIntersectionResult result;
|
RayToVoxelIntersectionResult result;
|
||||||
if (_tree) {
|
if (_tree) {
|
||||||
OctreeElement* element;
|
OctreeElement* element;
|
||||||
result.intersects = _tree->findRayIntersection(ray.origin, ray.direction, element, result.distance, result.face);
|
result.intersects = _tree->findRayIntersection(ray.origin, ray.direction, element, result.distance, result.face,
|
||||||
|
lockType, &result.accurate);
|
||||||
if (result.intersects) {
|
if (result.intersects) {
|
||||||
VoxelTreeElement* voxel = (VoxelTreeElement*)element;
|
VoxelTreeElement* voxel = (VoxelTreeElement*)element;
|
||||||
result.voxel.x = voxel->getCorner().x;
|
result.voxel.x = voxel->getCorner().x;
|
||||||
|
|
|
@ -35,17 +35,16 @@ public:
|
||||||
void setVoxelTree(VoxelTree* tree) { _tree = tree; }
|
void setVoxelTree(VoxelTree* tree) { _tree = tree; }
|
||||||
void setUndoStack(QUndoStack* undoStack) { _undoStack = undoStack; }
|
void setUndoStack(QUndoStack* undoStack) { _undoStack = undoStack; }
|
||||||
|
|
||||||
public slots:
|
public:
|
||||||
|
|
||||||
/// provide the world scale
|
/// provide the world scale
|
||||||
const int getTreeScale() const { return TREE_SCALE; }
|
Q_INVOKABLE const int getTreeScale() const { return TREE_SCALE; }
|
||||||
|
|
||||||
/// checks the local voxel tree for a voxel at the specified location and scale
|
/// checks the local voxel tree for a voxel at the specified location and scale
|
||||||
/// \param x the x-coordinate of the voxel (in meter units)
|
/// \param x the x-coordinate of the voxel (in meter units)
|
||||||
/// \param y the y-coordinate of the voxel (in meter units)
|
/// \param y the y-coordinate of the voxel (in meter units)
|
||||||
/// \param z the z-coordinate of the voxel (in meter units)
|
/// \param z the z-coordinate of the voxel (in meter units)
|
||||||
/// \param scale the scale of the voxel (in meter units)
|
/// \param scale the scale of the voxel (in meter units)
|
||||||
VoxelDetail getVoxelAt(float x, float y, float z, float scale);
|
Q_INVOKABLE VoxelDetail getVoxelAt(float x, float y, float z, float scale);
|
||||||
|
|
||||||
/// queues the creation of a voxel which will be sent by calling process on the PacketSender
|
/// queues the creation of a voxel which will be sent by calling process on the PacketSender
|
||||||
/// \param x the x-coordinate of the voxel (in meter units)
|
/// \param x the x-coordinate of the voxel (in meter units)
|
||||||
|
@ -55,7 +54,7 @@ public slots:
|
||||||
/// \param red the R value for RGB color of voxel
|
/// \param red the R value for RGB color of voxel
|
||||||
/// \param green the G value for RGB color of voxel
|
/// \param green the G value for RGB color of voxel
|
||||||
/// \param blue the B value for RGB color of voxel
|
/// \param blue the B value for RGB color of voxel
|
||||||
void setVoxelNonDestructive(float x, float y, float z, float scale, uchar red, uchar green, uchar blue);
|
Q_INVOKABLE void setVoxelNonDestructive(float x, float y, float z, float scale, uchar red, uchar green, uchar blue);
|
||||||
|
|
||||||
/// queues the destructive creation of a voxel which will be sent by calling process on the PacketSender
|
/// queues the destructive creation of a voxel which will be sent by calling process on the PacketSender
|
||||||
/// \param x the x-coordinate of the voxel (in meter units)
|
/// \param x the x-coordinate of the voxel (in meter units)
|
||||||
|
@ -65,27 +64,36 @@ public slots:
|
||||||
/// \param red the R value for RGB color of voxel
|
/// \param red the R value for RGB color of voxel
|
||||||
/// \param green the G value for RGB color of voxel
|
/// \param green the G value for RGB color of voxel
|
||||||
/// \param blue the B value for RGB color of voxel
|
/// \param blue the B value for RGB color of voxel
|
||||||
void setVoxel(float x, float y, float z, float scale, uchar red, uchar green, uchar blue);
|
Q_INVOKABLE void setVoxel(float x, float y, float z, float scale, uchar red, uchar green, uchar blue);
|
||||||
|
|
||||||
/// queues the deletion of a voxel, sent by calling process on the PacketSender
|
/// queues the deletion of a voxel, sent by calling process on the PacketSender
|
||||||
/// \param x the x-coordinate of the voxel (in meter units)
|
/// \param x the x-coordinate of the voxel (in meter units)
|
||||||
/// \param y the y-coordinate of the voxel (in meter units)
|
/// \param y the y-coordinate of the voxel (in meter units)
|
||||||
/// \param z the z-coordinate of the voxel (in meter units)
|
/// \param z the z-coordinate of the voxel (in meter units)
|
||||||
/// \param scale the scale of the voxel (in meter units)
|
/// \param scale the scale of the voxel (in meter units)
|
||||||
void eraseVoxel(float x, float y, float z, float scale);
|
Q_INVOKABLE void eraseVoxel(float x, float y, float z, float scale);
|
||||||
|
|
||||||
/// If the scripting context has visible voxels, this will determine a ray intersection
|
/// If the scripting context has visible voxels, this will determine a ray intersection, the results
|
||||||
RayToVoxelIntersectionResult findRayIntersection(const PickRay& ray);
|
/// may be inaccurate if the engine is unable to access the visible voxels, in which case result.accurate
|
||||||
|
/// will be false.
|
||||||
|
Q_INVOKABLE RayToVoxelIntersectionResult findRayIntersection(const PickRay& ray);
|
||||||
|
|
||||||
|
/// If the scripting context has visible voxels, this will determine a ray intersection, and will block in
|
||||||
|
/// order to return an accurate result
|
||||||
|
Q_INVOKABLE RayToVoxelIntersectionResult findRayIntersectionBlocking(const PickRay& ray);
|
||||||
|
|
||||||
/// returns a voxel space axis aligned vector for the face, useful in doing voxel math
|
/// returns a voxel space axis aligned vector for the face, useful in doing voxel math
|
||||||
glm::vec3 getFaceVector(const QString& face);
|
Q_INVOKABLE glm::vec3 getFaceVector(const QString& face);
|
||||||
|
|
||||||
/// checks the local voxel tree for the smallest voxel enclosing the point
|
/// checks the local voxel tree for the smallest voxel enclosing the point
|
||||||
/// \param point the x,y,z coordinates of the point (in meter units)
|
/// \param point the x,y,z coordinates of the point (in meter units)
|
||||||
/// \return VoxelDetail - if no voxel encloses the point then VoxelDetail items will be 0
|
/// \return VoxelDetail - if no voxel encloses the point then VoxelDetail items will be 0
|
||||||
VoxelDetail getVoxelEnclosingPoint(const glm::vec3& point);
|
Q_INVOKABLE VoxelDetail getVoxelEnclosingPoint(const glm::vec3& point);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/// actually does the work of finding the ray intersection, can be called in locking mode or tryLock mode
|
||||||
|
RayToVoxelIntersectionResult findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType);
|
||||||
|
|
||||||
void queueVoxelAdd(PacketType addPacketType, VoxelDetail& addVoxelDetails);
|
void queueVoxelAdd(PacketType addPacketType, VoxelDetail& addVoxelDetails);
|
||||||
VoxelTree* _tree;
|
VoxelTree* _tree;
|
||||||
QUndoStack* _undoStack;
|
QUndoStack* _undoStack;
|
||||||
|
|
Loading…
Reference in a new issue