mirror of
https://github.com/overte-org/overte.git
synced 2025-04-07 15:34:05 +02:00
[WL21389] Addresses physics library dependency and has some other fixes (details below).
* Addresses physics library dependency by moving computeShapeInfo override from ShapeEntityItem (which is within Entities Library) to RenderableShapeEntityItem (which is in Entities-Renderer Library). ** Entities-Renderer library already links against the physic library. ** Per discussion with Andrew Meadows: In order to ShapeEntityItem to be utilized the library dependency between the Entity and Physics library would need to be resolved to avoid the cyclical reliance which isn't in the scope of this ticket. * Updates shapeSpawner test script from the default clone of basicEntityTest\entitySpawner.js ** Objects now have a finite lifetime ** Script now cleans up the objects created when the script ends ** Also moved some adjustable properties out into var aliases at the top of the file for easier/less error prone tweaking. Should probably add one for the shapeType. * Fixes some issues with validateShapeType helper function * Removed naive attempt at including physics library within entities library. * Transferred some todos from notes * Fixed some formatting NOTE(s): This compiles and runs. Cylinder is spawned and treated as CYLINDER_Y. TODO(s): * Add tweakable var for shapeType within shapeSpawner.js * Vet and verify other shapes. * Add in edge case handling. * Add in support for other shapes to ShapeInfo infrastructure. Changes to be committed: modified: libraries/entities-renderer/src/RenderableShapeEntityItem.cpp modified: libraries/entities-renderer/src/RenderableShapeEntityItem.h modified: libraries/entities/CMakeLists.txt modified: libraries/entities/src/ShapeEntityItem.cpp modified: libraries/entities/src/ShapeEntityItem.h modified: libraries/physics/src/ShapeFactory.cpp modified: libraries/shared/src/ShapeInfo.cpp modified: scripts/developer/tests/basicEntityTest/shapeSpawner.js
This commit is contained in:
parent
5bc38bd7f0
commit
75403124b6
8 changed files with 226 additions and 209 deletions
|
@ -16,6 +16,7 @@
|
|||
#include <StencilMaskPass.h>
|
||||
#include <GeometryCache.h>
|
||||
#include <PerfStat.h>
|
||||
#include <ShapeFactory.h>
|
||||
|
||||
#include <render-utils/simple_vert.h>
|
||||
#include <render-utils/simple_frag.h>
|
||||
|
@ -48,11 +49,12 @@ RenderableShapeEntityItem::Pointer RenderableShapeEntityItem::baseFactory(const
|
|||
}
|
||||
|
||||
EntityItemPointer RenderableShapeEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
auto result = baseFactory(entityID, properties);
|
||||
auto result = baseFactory(entityID, properties);
|
||||
|
||||
qCDebug(entities) << "Creating RenderableShapeEntityItem( " << result->_name << " ): " << result.get() << " ID: " << result->_id;
|
||||
//TODO_CUSACK: Remove this before final PN
|
||||
qCDebug(entities) << "Creating RenderableShapeEntityItem( " << result->_name << " ): " << result.get() << " ID: " << result->_id;
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
EntityItemPointer RenderableShapeEntityItem::boxFactory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
|
@ -86,6 +88,23 @@ bool RenderableShapeEntityItem::isTransparent() {
|
|||
}
|
||||
}
|
||||
|
||||
void RenderableShapeEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||
|
||||
if (_collisionShapeType == ShapeType::SHAPE_TYPE_NONE) {
|
||||
if (_shape == entity::Shape::NUM_SHAPES)
|
||||
{
|
||||
EntityItem::computeShapeInfo(info);
|
||||
|
||||
//--EARLY EXIT--( allow default handling to process )
|
||||
return;
|
||||
}
|
||||
|
||||
_collisionShapeType = ShapeFactory::computeShapeType(getShape(), getDimensions());
|
||||
}
|
||||
|
||||
return EntityItem::computeShapeInfo(info);
|
||||
}
|
||||
|
||||
void RenderableShapeEntityItem::render(RenderArgs* args) {
|
||||
PerformanceTimer perfTimer("RenderableShapeEntityItem::render");
|
||||
//Q_ASSERT(getType() == EntityTypes::Shape);
|
||||
|
|
|
@ -28,6 +28,8 @@ public:
|
|||
|
||||
bool isTransparent() override;
|
||||
|
||||
void computeShapeInfo(ShapeInfo& info);
|
||||
|
||||
private:
|
||||
std::unique_ptr<Procedural> _procedural { nullptr };
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
set(TARGET_NAME entities)
|
||||
setup_hifi_library(Network Script)
|
||||
link_hifi_libraries(shared networking octree avatars physics)
|
||||
link_hifi_libraries(shared networking octree avatars)
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include <QtCore/QDebug>
|
||||
|
||||
#include <GeometryUtil.h>
|
||||
#include <ShapeFactory.h>
|
||||
|
||||
#include "EntitiesLogging.h"
|
||||
#include "EntityItemProperties.h"
|
||||
|
@ -59,11 +58,12 @@ ShapeEntityItem::Pointer ShapeEntityItem::baseFactory(const EntityItemID& entity
|
|||
}
|
||||
|
||||
EntityItemPointer ShapeEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
auto result = baseFactory(entityID, properties);
|
||||
auto result = baseFactory(entityID, properties);
|
||||
|
||||
qCDebug(entities) << "Creating ShapeEntityItem( " << result->_name << " ): " << result.get() << " ID: " << result->_id;
|
||||
//TODO_CUSACK: Remove this before final PN
|
||||
qCDebug(entities) << "Creating ShapeEntityItem( " << result->_name << " ): " << result.get() << " ID: " << result->_id;
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
EntityItemPointer ShapeEntityItem::boxFactory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
|
@ -96,9 +96,11 @@ void ShapeEntityItem::setShape(const entity::Shape& shape) {
|
|||
switch (_shape) {
|
||||
case entity::Shape::Cube:
|
||||
_type = EntityTypes::Box;
|
||||
_collisionShapeType = ShapeType::SHAPE_TYPE_BOX;
|
||||
break;
|
||||
case entity::Shape::Sphere:
|
||||
_type = EntityTypes::Sphere;
|
||||
_collisionShapeType = ShapeType::SHAPE_TYPE_ELLIPSOID;
|
||||
break;
|
||||
default:
|
||||
_type = EntityTypes::Shape;
|
||||
|
@ -170,46 +172,29 @@ void ShapeEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBit
|
|||
APPEND_ENTITY_PROPERTY(PROP_ALPHA, getAlpha());
|
||||
}
|
||||
|
||||
void ShapeEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||
|
||||
if ( _collisionShapeType == ShapeType::SHAPE_TYPE_NONE ) {
|
||||
if (_shape == entity::Shape::NUM_SHAPES)
|
||||
{
|
||||
EntityItem::computeShapeInfo(info);
|
||||
|
||||
//--EARLY EXIT--( allow default handling to process )
|
||||
return;
|
||||
}
|
||||
|
||||
_collisionShapeType = ShapeFactory::computeShapeType(getShape(), getDimensions());
|
||||
}
|
||||
|
||||
return EntityItem::computeShapeInfo(info);
|
||||
}
|
||||
|
||||
// This value specifes how the shape should be treated by physics calculations.
|
||||
// For now, all polys will act as spheres
|
||||
ShapeType ShapeEntityItem::getShapeType() const {
|
||||
//TODO_CUSACK: This needs to be retrieved from properties if possible
|
||||
// or stored within a new member and set during parsing of
|
||||
// the properties like setShape via set/get/readEntityProperties.
|
||||
// Perhaps if the _actual_ collisionShapeType is needed (the version that's in use
|
||||
// based on analysis of the shape's halfExtents when BulletLibrary collision shape was
|
||||
// created as opposed to the desired ShapeType is it possible to retrieve that information)?
|
||||
//if (_shape == entity::Shape::Cylinder) {
|
||||
// return SHAPE_TYPE_CYLINDER_Y;
|
||||
//}
|
||||
//TODO_CUSACK: This needs to be retrieved from properties if possible
|
||||
// or stored within a new member and set during parsing of
|
||||
// the properties like setShape via set/get/readEntityProperties.
|
||||
// Perhaps if the _actual_ collisionShapeType is needed (the version that's in use
|
||||
// based on analysis of the shape's halfExtents when BulletLibrary collision shape was
|
||||
// created as opposed to the desired ShapeType is it possible to retrieve that information)?
|
||||
//if (_shape == entity::Shape::Cylinder) {
|
||||
// return SHAPE_TYPE_CYLINDER_Y;
|
||||
//}
|
||||
|
||||
//// Original functionality: Everything not a cube, is treated like an ellipsoid/sphere
|
||||
//return (_shape == entity::Shape::Cube) ? SHAPE_TYPE_BOX : SHAPE_TYPE_ELLIPSOID;
|
||||
//// Original functionality: Everything not a cube, is treated like an ellipsoid/sphere
|
||||
//return (_shape == entity::Shape::Cube) ? SHAPE_TYPE_BOX : SHAPE_TYPE_ELLIPSOID;
|
||||
|
||||
if (_collisionShapeType == ShapeType::SHAPE_TYPE_NONE)
|
||||
{
|
||||
//--EARLY EXIT--( Maintain previous behavior of treating invalid as Ellipsoid/Sphere )
|
||||
return SHAPE_TYPE_ELLIPSOID;
|
||||
}
|
||||
//if (_collisionShapeType == ShapeType::SHAPE_TYPE_NONE)
|
||||
//{
|
||||
// //--EARLY EXIT--( Maintain previous behavior of treating invalid as Ellipsoid/Sphere )
|
||||
// return SHAPE_TYPE_ELLIPSOID;
|
||||
//}
|
||||
|
||||
return _collisionShapeType;
|
||||
return _collisionShapeType;
|
||||
}
|
||||
|
||||
void ShapeEntityItem::setColor(const rgbColor& value) {
|
||||
|
|
|
@ -84,7 +84,6 @@ public:
|
|||
QColor getQColor() const;
|
||||
void setColor(const QColor& value);
|
||||
|
||||
void computeShapeInfo(ShapeInfo& info);
|
||||
ShapeType getShapeType() const override;
|
||||
bool shouldBePhysical() const override { return !isDead(); }
|
||||
|
||||
|
|
|
@ -247,121 +247,120 @@ void deleteStaticMeshArray(btTriangleIndexVertexArray* dataArray) {
|
|||
delete dataArray;
|
||||
}
|
||||
|
||||
ShapeType validateShapeType(ShapeType type, const glm::vec3 &halfExtents, btCollisionShape *outCollisionShape = nullptr)
|
||||
ShapeType validateShapeType(ShapeType type, const glm::vec3 &halfExtents, btCollisionShape **outCollisionShape = NULL)
|
||||
{
|
||||
if ((type == SHAPE_TYPE_SPHERE) || (type == SHAPE_TYPE_ELLIPSOID))
|
||||
{
|
||||
float radius = halfExtents.x;
|
||||
const float MIN_RADIUS = 0.001f;
|
||||
const float MIN_RELATIVE_SPHERICAL_ERROR = 0.001f;
|
||||
if (radius > MIN_RADIUS
|
||||
&& fabsf(radius - halfExtents.y) / radius < MIN_RELATIVE_SPHERICAL_ERROR
|
||||
&& fabsf(radius - halfExtents.z) / radius < MIN_RELATIVE_SPHERICAL_ERROR) {
|
||||
// close enough to true sphere
|
||||
if (outCollisionShape) {
|
||||
outCollisionShape = new btSphereShape(radius);
|
||||
}
|
||||
if ((type == SHAPE_TYPE_SPHERE) || (type == SHAPE_TYPE_ELLIPSOID))
|
||||
{
|
||||
float radius = halfExtents.x;
|
||||
const float MIN_RADIUS = 0.001f;
|
||||
const float MIN_RELATIVE_SPHERICAL_ERROR = 0.001f;
|
||||
if (radius > MIN_RADIUS
|
||||
&& fabsf(radius - halfExtents.y) / radius < MIN_RELATIVE_SPHERICAL_ERROR
|
||||
&& fabsf(radius - halfExtents.z) / radius < MIN_RELATIVE_SPHERICAL_ERROR) {
|
||||
// close enough to true sphere
|
||||
if (outCollisionShape) {
|
||||
(*outCollisionShape) = new btSphereShape(radius);
|
||||
}
|
||||
|
||||
return SHAPE_TYPE_SPHERE;
|
||||
}
|
||||
else {
|
||||
ShapeInfo::PointList points;
|
||||
points.reserve(NUM_UNIT_SPHERE_DIRECTIONS);
|
||||
for (uint32_t i = 0; i < NUM_UNIT_SPHERE_DIRECTIONS; ++i) {
|
||||
points.push_back(bulletToGLM(_unitSphereDirections[i]) * halfExtents);
|
||||
}
|
||||
if (outCollisionShape) {
|
||||
outCollisionShape = createConvexHull(points);
|
||||
}
|
||||
return SHAPE_TYPE_SPHERE;
|
||||
}
|
||||
else {
|
||||
ShapeInfo::PointList points;
|
||||
points.reserve(NUM_UNIT_SPHERE_DIRECTIONS);
|
||||
for (uint32_t i = 0; i < NUM_UNIT_SPHERE_DIRECTIONS; ++i) {
|
||||
points.push_back(bulletToGLM(_unitSphereDirections[i]) * halfExtents);
|
||||
}
|
||||
if (outCollisionShape) {
|
||||
(*outCollisionShape) = createConvexHull(points);
|
||||
}
|
||||
|
||||
return SHAPE_TYPE_ELLIPSOID;
|
||||
}
|
||||
}
|
||||
else if ((type == SHAPE_TYPE_CYLINDER_X) || (type == SHAPE_TYPE_CYLINDER_Y) || (type == SHAPE_TYPE_CYLINDER_Z))
|
||||
{
|
||||
const btVector3 btHalfExtents(halfExtents.x, halfExtents.y, halfExtents.z);
|
||||
if ((halfExtents.y > halfExtents.x) && (halfExtents.y > halfExtents.z)) {
|
||||
if (outCollisionShape) {
|
||||
outCollisionShape = new btCylinderShape(btHalfExtents);
|
||||
}
|
||||
return SHAPE_TYPE_ELLIPSOID;
|
||||
}
|
||||
}
|
||||
else if ((type == SHAPE_TYPE_CYLINDER_X) || (type == SHAPE_TYPE_CYLINDER_Y) || (type == SHAPE_TYPE_CYLINDER_Z))
|
||||
{
|
||||
// TODO_CUSACK: Should allow for minor variance along axes?
|
||||
const btVector3 btHalfExtents(halfExtents.x, halfExtents.y, halfExtents.z);
|
||||
if ((halfExtents.y >= halfExtents.x) && (halfExtents.y >= halfExtents.z)) {
|
||||
if (outCollisionShape) {
|
||||
(*outCollisionShape) = new btCylinderShape(btHalfExtents);
|
||||
}
|
||||
|
||||
return SHAPE_TYPE_CYLINDER_Y;
|
||||
}
|
||||
else if (halfExtents.x > halfExtents.z) {
|
||||
if (outCollisionShape) {
|
||||
outCollisionShape = new btCylinderShapeX(btHalfExtents);
|
||||
}
|
||||
return SHAPE_TYPE_CYLINDER_Y;
|
||||
}
|
||||
else if (halfExtents.x >= halfExtents.z) {
|
||||
if (outCollisionShape) {
|
||||
(*outCollisionShape) = new btCylinderShapeX(btHalfExtents);
|
||||
}
|
||||
|
||||
return SHAPE_TYPE_CYLINDER_X;
|
||||
}
|
||||
else if (halfExtents.z > halfExtents.x) {
|
||||
if (outCollisionShape) {
|
||||
outCollisionShape = new btCylinderShapeZ(btHalfExtents);
|
||||
}
|
||||
return SHAPE_TYPE_CYLINDER_X;
|
||||
}
|
||||
else if (halfExtents.z > halfExtents.x) {
|
||||
if (outCollisionShape) {
|
||||
(*outCollisionShape) = new btCylinderShapeZ(btHalfExtents);
|
||||
}
|
||||
|
||||
return SHAPE_TYPE_CYLINDER_Z;
|
||||
}
|
||||
else //...there was no major axis, treat as a sphere
|
||||
{
|
||||
ShapeType cylinderFallback = validateShapeType(SHAPE_TYPE_ELLIPSOID, halfExtents, outCollisionShape);
|
||||
return cylinderFallback;
|
||||
}
|
||||
}
|
||||
return SHAPE_TYPE_CYLINDER_Z;
|
||||
}
|
||||
else //...there was no major axis, treat as a sphere
|
||||
{
|
||||
ShapeType cylinderFallback = validateShapeType(SHAPE_TYPE_ELLIPSOID, halfExtents, outCollisionShape);
|
||||
return cylinderFallback;
|
||||
}
|
||||
}
|
||||
|
||||
//Got here, then you are what you are along with outCollisionShape
|
||||
return type;
|
||||
//Got here, then you are what you are along with outCollisionShape
|
||||
return type;
|
||||
}
|
||||
|
||||
ShapeType ShapeFactory::computeShapeType(entity::Shape shape, const glm::vec3 &entityDimensions) {
|
||||
if ( shape == entity::Shape::NUM_SHAPES ) {
|
||||
//--EARLY EXIT--
|
||||
return SHAPE_TYPE_NONE;
|
||||
}
|
||||
if (shape == entity::Shape::NUM_SHAPES) {
|
||||
//--EARLY EXIT--
|
||||
return SHAPE_TYPE_NONE;
|
||||
}
|
||||
|
||||
const glm::vec3 halfExtents = entityDimensions * 0.5f;
|
||||
switch (shape){
|
||||
case entity::Shape::Triangle: {
|
||||
//TODO_CUSACK: Implement this
|
||||
return validateShapeType(SHAPE_TYPE_ELLIPSOID, halfExtents);
|
||||
}
|
||||
const glm::vec3 halfExtents = entityDimensions * 0.5f;
|
||||
switch (shape){
|
||||
case entity::Shape::Triangle: {
|
||||
//TODO_CUSACK: Implement this
|
||||
return validateShapeType(SHAPE_TYPE_ELLIPSOID, halfExtents);
|
||||
}
|
||||
//Note: Intentional Fallthrough from Quad to Cube
|
||||
case entity::Shape::Quad:
|
||||
case entity::Shape::Cube: {
|
||||
return SHAPE_TYPE_BOX;
|
||||
}
|
||||
//Note: Intentional Fallthrough from Hexagon to Sphere
|
||||
case entity::Shape::Hexagon:
|
||||
case entity::Shape::Octagon:
|
||||
case entity::Shape::Circle:
|
||||
case entity::Shape::Sphere: {
|
||||
return validateShapeType(SHAPE_TYPE_SPHERE, halfExtents);
|
||||
}
|
||||
|
||||
//Note: Intentional Fallthrough from Quad to Cube
|
||||
case entity::Shape::Quad:
|
||||
case entity::Shape::Cube: {
|
||||
return SHAPE_TYPE_BOX;
|
||||
}
|
||||
case entity::Shape::Cylinder: {
|
||||
return validateShapeType(SHAPE_TYPE_CYLINDER_Y, halfExtents);
|
||||
}
|
||||
|
||||
//Note: Intentional Fallthrough from Hexagon to Sphere
|
||||
case entity::Shape::Hexagon:
|
||||
case entity::Shape::Octagon:
|
||||
case entity::Shape::Circle:
|
||||
case entity::Shape::Sphere: {
|
||||
return validateShapeType(SHAPE_TYPE_SPHERE, halfExtents);
|
||||
}
|
||||
//Note: Intentional Fallthrough from Tetrahedron to Icosahedron
|
||||
case entity::Shape::Tetrahedron:
|
||||
case entity::Shape::Octahedron:
|
||||
case entity::Shape::Dodecahedron:
|
||||
case entity::Shape::Icosahedron: {
|
||||
|
||||
case entity::Shape::Cylinder: {
|
||||
return validateShapeType(SHAPE_TYPE_CYLINDER_Y, halfExtents);
|
||||
}
|
||||
//TODO_CUSACK: Implement the hedrons
|
||||
return validateShapeType(SHAPE_TYPE_ELLIPSOID, halfExtents);
|
||||
}
|
||||
|
||||
//Note: Intentional Fallthrough from Tetrahedron to Icosahedron
|
||||
case entity::Shape::Tetrahedron:
|
||||
case entity::Shape::Octahedron:
|
||||
case entity::Shape::Dodecahedron:
|
||||
case entity::Shape::Icosahedron: {
|
||||
//Note: Intentional Fallthrough from Torus to default.
|
||||
case entity::Shape::Torus:
|
||||
case entity::Shape::Cone: {
|
||||
|
||||
//TODO_CUSACK: Implement the hedrons
|
||||
return validateShapeType( SHAPE_TYPE_ELLIPSOID, halfExtents );
|
||||
}
|
||||
|
||||
//Note: Intentional Fallthrough from Torus to default.
|
||||
case entity::Shape::Torus:
|
||||
case entity::Shape::Cone: {
|
||||
|
||||
// These types are currently unsupported
|
||||
}
|
||||
default:
|
||||
return SHAPE_TYPE_NONE;
|
||||
}
|
||||
// These types are currently unsupported
|
||||
}
|
||||
default:
|
||||
return SHAPE_TYPE_NONE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -379,7 +378,7 @@ const btCollisionShape* ShapeFactory::createShapeFromInfo(const ShapeInfo& info)
|
|||
// shape = new btSphereShape(radius);
|
||||
//}
|
||||
//break;
|
||||
case SHAPE_TYPE_SPHERE:
|
||||
case SHAPE_TYPE_SPHERE:
|
||||
case SHAPE_TYPE_ELLIPSOID: {
|
||||
glm::vec3 halfExtents = info.getHalfExtents();
|
||||
//float radius = halfExtents.x;
|
||||
|
@ -399,9 +398,11 @@ const btCollisionShape* ShapeFactory::createShapeFromInfo(const ShapeInfo& info)
|
|||
// shape = createConvexHull(points);
|
||||
//}
|
||||
|
||||
validateShapeType(SHAPE_TYPE_ELLIPSOID, halfExtents, shape);
|
||||
validateShapeType(SHAPE_TYPE_ELLIPSOID, halfExtents, &shape);
|
||||
}
|
||||
break;
|
||||
//TODO_CUSACK: Add Capsules to vetting/validation process for
|
||||
// type checks.
|
||||
case SHAPE_TYPE_CAPSULE_Y: {
|
||||
glm::vec3 halfExtents = info.getHalfExtents();
|
||||
float radius = halfExtents.x;
|
||||
|
@ -409,42 +410,44 @@ const btCollisionShape* ShapeFactory::createShapeFromInfo(const ShapeInfo& info)
|
|||
shape = new btCapsuleShape(radius, height);
|
||||
}
|
||||
break;
|
||||
case SHAPE_TYPE_CAPSULE_X: {
|
||||
glm::vec3 halfExtents = info.getHalfExtents();
|
||||
float radius = halfExtents.y;
|
||||
float height = 2.0f * halfExtents.x;
|
||||
shape = new btCapsuleShapeX(radius, height);
|
||||
}
|
||||
break;
|
||||
case SHAPE_TYPE_CAPSULE_Z: {
|
||||
glm::vec3 halfExtents = info.getHalfExtents();
|
||||
float radius = halfExtents.x;
|
||||
float height = 2.0f * halfExtents.z;
|
||||
shape = new btCapsuleShapeZ(radius, height);
|
||||
}
|
||||
break;
|
||||
case SHAPE_TYPE_CYLINDER_X:
|
||||
case SHAPE_TYPE_CYLINDER_Z:
|
||||
case SHAPE_TYPE_CYLINDER_Y: {
|
||||
// TODO_CUSACK: Should allow for minor variance along axes.
|
||||
const glm::vec3 halfExtents = info.getHalfExtents();
|
||||
//const btVector3 btHalfExtents(halfExtents.x, halfExtents.y, halfExtents.z);
|
||||
//if ((halfExtents.y > halfExtents.x) && (halfExtents.y > halfExtents.z)) {
|
||||
// shape = new btCylinderShape(btHalfExtents);
|
||||
//}
|
||||
//else if (halfExtents.x > halfExtents.z) {
|
||||
// shape = new btCylinderShapeX(btHalfExtents);
|
||||
//}
|
||||
//else if (halfExtents.z > halfExtents.x) {
|
||||
// shape = new btCylinderShapeZ(btHalfExtents);
|
||||
//}
|
||||
//else //...there was no major axis, treat as a sphere
|
||||
//{
|
||||
// //TODO_CUSACK: Shunt to ELLIPSOID handling
|
||||
//}
|
||||
validateShapeType(SHAPE_TYPE_CYLINDER_Y, halfExtents, shape);
|
||||
}
|
||||
break;
|
||||
case SHAPE_TYPE_CAPSULE_X: {
|
||||
glm::vec3 halfExtents = info.getHalfExtents();
|
||||
float radius = halfExtents.y;
|
||||
float height = 2.0f * halfExtents.x;
|
||||
shape = new btCapsuleShapeX(radius, height);
|
||||
}
|
||||
break;
|
||||
case SHAPE_TYPE_CAPSULE_Z: {
|
||||
glm::vec3 halfExtents = info.getHalfExtents();
|
||||
float radius = halfExtents.x;
|
||||
float height = 2.0f * halfExtents.z;
|
||||
shape = new btCapsuleShapeZ(radius, height);
|
||||
}
|
||||
break;
|
||||
case SHAPE_TYPE_CYLINDER_X:
|
||||
case SHAPE_TYPE_CYLINDER_Z:
|
||||
case SHAPE_TYPE_CYLINDER_Y: {
|
||||
// TODO_CUSACK: Should allow for minor variance along axes.
|
||||
const glm::vec3 halfExtents = info.getHalfExtents();
|
||||
//const btVector3 btHalfExtents(halfExtents.x, halfExtents.y, halfExtents.z);
|
||||
//if ((halfExtents.y > halfExtents.x) && (halfExtents.y > halfExtents.z)) {
|
||||
// shape = new btCylinderShape(btHalfExtents);
|
||||
//}
|
||||
//else if (halfExtents.x > halfExtents.z) {
|
||||
// shape = new btCylinderShapeX(btHalfExtents);
|
||||
//}
|
||||
//else if (halfExtents.z > halfExtents.x) {
|
||||
// shape = new btCylinderShapeZ(btHalfExtents);
|
||||
//}
|
||||
//else //...there was no major axis, treat as a sphere
|
||||
//{
|
||||
// //TODO_CUSACK: Shunt to ELLIPSOID handling
|
||||
//}
|
||||
validateShapeType(SHAPE_TYPE_CYLINDER_Y, halfExtents, &shape);
|
||||
}
|
||||
break;
|
||||
//TODO_CUSACK: Add compound and simple hull to vetting/validation
|
||||
// process for types.
|
||||
case SHAPE_TYPE_COMPOUND:
|
||||
case SHAPE_TYPE_SIMPLE_HULL: {
|
||||
const ShapeInfo::PointCollection& pointCollection = info.getPointCollection();
|
||||
|
|
|
@ -29,7 +29,8 @@ void ShapeInfo::clear() {
|
|||
}
|
||||
|
||||
void ShapeInfo::setParams(ShapeType type, const glm::vec3& halfExtents, QString url) {
|
||||
_url = "";
|
||||
//TODO_CUSACK: Does this need additional cases and handling added?
|
||||
_url = "";
|
||||
_type = type;
|
||||
setHalfExtents(halfExtents);
|
||||
switch(type) {
|
||||
|
@ -55,6 +56,8 @@ void ShapeInfo::setParams(ShapeType type, const glm::vec3& halfExtents, QString
|
|||
}
|
||||
|
||||
void ShapeInfo::setBox(const glm::vec3& halfExtents) {
|
||||
//TODO_CUSACK: Should this pointlist clearance added in case
|
||||
// this is a re-purposed instance?
|
||||
_url = "";
|
||||
_type = SHAPE_TYPE_BOX;
|
||||
setHalfExtents(halfExtents);
|
||||
|
@ -62,6 +65,8 @@ void ShapeInfo::setBox(const glm::vec3& halfExtents) {
|
|||
}
|
||||
|
||||
void ShapeInfo::setSphere(float radius) {
|
||||
//TODO_CUSACK: Should this pointlist clearance added in case
|
||||
// this is a re-purposed instance?
|
||||
_url = "";
|
||||
_type = SHAPE_TYPE_SPHERE;
|
||||
radius = glm::max(radius, MIN_HALF_EXTENT);
|
||||
|
@ -70,12 +75,17 @@ void ShapeInfo::setSphere(float radius) {
|
|||
}
|
||||
|
||||
void ShapeInfo::setPointCollection(const ShapeInfo::PointCollection& pointCollection) {
|
||||
//TODO_CUSACK: Should this have protection against inadvertant clearance and type
|
||||
// resetting? If for some reason this was called and point list was and is emtpy
|
||||
// would we still wish to clear out everything?
|
||||
_pointCollection = pointCollection;
|
||||
_type = (_pointCollection.size() > 0) ? SHAPE_TYPE_COMPOUND : SHAPE_TYPE_NONE;
|
||||
_doubleHashKey.clear();
|
||||
}
|
||||
|
||||
void ShapeInfo::setCapsuleY(float radius, float halfHeight) {
|
||||
//TODO_CUSACK: Should this pointlist clearance added in case
|
||||
// this is a re-purposed instance?
|
||||
_url = "";
|
||||
_type = SHAPE_TYPE_CAPSULE_Y;
|
||||
radius = glm::max(radius, MIN_HALF_EXTENT);
|
||||
|
@ -117,6 +127,7 @@ int ShapeInfo::getLargestSubshapePointCount() const {
|
|||
}
|
||||
|
||||
float ShapeInfo::computeVolume() const {
|
||||
//TODO_CUSACK: Add support for other ShapeTypes.
|
||||
const float DEFAULT_VOLUME = 1.0f;
|
||||
float volume = DEFAULT_VOLUME;
|
||||
switch(_type) {
|
||||
|
@ -150,6 +161,7 @@ float ShapeInfo::computeVolume() const {
|
|||
}
|
||||
|
||||
bool ShapeInfo::contains(const glm::vec3& point) const {
|
||||
//TODO_CUSACK: Add support for other ShapeTypes like Ellipsoid/Compound.
|
||||
switch(_type) {
|
||||
case SHAPE_TYPE_SPHERE:
|
||||
return glm::length(point) <= _halfExtents.x;
|
||||
|
|
|
@ -1,33 +1,30 @@
|
|||
var orientation = Camera.getOrientation();
|
||||
orientation = Quat.safeEulerAngles(orientation);
|
||||
orientation.x = 0;
|
||||
orientation = Quat.fromVec3Degrees(orientation);
|
||||
var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getForward(orientation)));
|
||||
// compute a position to create the object relative to avatar
|
||||
var forwardOffset = Vec3.multiply(2.0, Quat.getFront(MyAvatar.orientation));
|
||||
var objectPosition = Vec3.sum(MyAvatar.position, forwardOffset);
|
||||
|
||||
// Math.random ensures no caching of script
|
||||
var SCRIPT_URL = Script.resolvePath("myEntityScript.js")
|
||||
var LIFETIME = 1800; //seconds
|
||||
var DIM_HEIGHT = 1, DIM_WIDTH = 1, DIM_DEPTH = 1;
|
||||
var COLOR_R = 100, COLOR_G = 10, COLOR_B = 200;
|
||||
|
||||
var myEntity = Entities.addEntity({
|
||||
name: "ShapeSpawnTest",
|
||||
type: "Shape",
|
||||
shape: "Cylinder",
|
||||
color: {
|
||||
red: 200,
|
||||
green: 10,
|
||||
blue: 200
|
||||
},
|
||||
position: center,
|
||||
dimensions: {
|
||||
x: 1,
|
||||
y: 1,
|
||||
z: 1
|
||||
},
|
||||
script: SCRIPT_URL
|
||||
})
|
||||
var properties = {
|
||||
name: "ShapeSpawnTest",
|
||||
type: "Shape",
|
||||
shape: "Cylinder",
|
||||
dimensions: {x: DIM_WIDTH, y: DIM_HEIGHT, z: DIM_DEPTH},
|
||||
color: {red: COLOR_R, green: COLOR_G, blue: COLOR_B},
|
||||
position: objectPosition,
|
||||
lifetime: LIFETIME,
|
||||
};
|
||||
|
||||
// create the object
|
||||
var entityId = Entities.addEntity(properties);
|
||||
|
||||
function cleanup() {
|
||||
Entities.deleteEntity(entityId);
|
||||
}
|
||||
|
||||
// delete the object when this script is stopped
|
||||
Script.scriptEnding.connect(cleanup);
|
||||
|
||||
|
||||
function cleanup() {
|
||||
// Entities.deleteEntity(myEntity);
|
||||
}
|
||||
|
||||
Script.scriptEnding.connect(cleanup);
|
||||
|
|
Loading…
Reference in a new issue