mirror of
https://github.com/JulianGro/overte.git
synced 2025-08-17 18:22:14 +02:00
bucky balls!
This commit is contained in:
parent
e3a77ef139
commit
d1e9c25d00
3 changed files with 168 additions and 2 deletions
|
@ -19,6 +19,13 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
const float RANGE_BBALLS = 0.5f;
|
||||
const float SIZE_BBALLS = 0.02f;
|
||||
const float CORNER_BBALLS = 2.f;
|
||||
const float GRAVITY_BBALLS = -0.25f;
|
||||
const float BBALLS_ATTRACTION_DISTANCE = SIZE_BBALLS / 2.f;
|
||||
|
||||
const float FINGERTIP_COLLISION_RADIUS = SIZE_BBALLS / 2.f;
|
||||
const float FINGERTIP_VOXEL_SIZE = 0.05;
|
||||
const int TOY_BALL_HAND = 1;
|
||||
const float TOY_BALL_RADIUS = 0.05f;
|
||||
|
@ -40,6 +47,7 @@ const xColor TOY_BALL_ON_SERVER_COLOR[] =
|
|||
{ 255, 0, 255 },
|
||||
};
|
||||
|
||||
|
||||
Hand::Hand(Avatar* owningAvatar) :
|
||||
HandData((AvatarData*)owningAvatar),
|
||||
|
||||
|
@ -67,6 +75,35 @@ Hand::Hand(Avatar* owningAvatar) :
|
|||
// the throw and catch sounds should not loopback, we'll play them locally
|
||||
_throwInjector.setShouldLoopback(false);
|
||||
_catchInjector.setShouldLoopback(false);
|
||||
|
||||
// Make some bucky balls for the avatar
|
||||
_bballIsGrabbed[0] = 0;
|
||||
_bballIsGrabbed[1] = 0;
|
||||
if (_owningAvatar && _owningAvatar->getOwningNode() == NULL) {
|
||||
printf("Creating buckyballs...\n");
|
||||
for (int i = 0; i < NUM_BBALLS; i++) {
|
||||
_bballPosition[i] = CORNER_BBALLS + randVector() * RANGE_BBALLS;
|
||||
int element = (rand() % 3);
|
||||
if (element == 0) {
|
||||
_bballRadius[i] = SIZE_BBALLS;
|
||||
_bballColor[i] = glm::vec3(0.13f, 0.55f, 0.13f);
|
||||
} else if (element == 1) {
|
||||
_bballRadius[i] = SIZE_BBALLS / 2.f;
|
||||
_bballColor[i] = glm::vec3(0.64f, 0.16f, 0.16f);
|
||||
|
||||
} else {
|
||||
_bballRadius[i] = SIZE_BBALLS * 2.f;
|
||||
_bballColor[i] = glm::vec3(0.31f, 0.58f, 0.80f);
|
||||
}
|
||||
_bballColliding[i] = 0.f;
|
||||
_bballElement[i] = element;
|
||||
if (_bballElement[i] != 1) {
|
||||
_bballVelocity[i] = randVector() * 0.3f;
|
||||
} else {
|
||||
_bballVelocity[i] = glm::vec3(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Hand::init() {
|
||||
|
@ -82,6 +119,111 @@ void Hand::init() {
|
|||
void Hand::reset() {
|
||||
}
|
||||
|
||||
void Hand::grabBuckyBalls(PalmData& palm, const glm::vec3& fingerTipPosition, float deltaTime) {
|
||||
float penetration;
|
||||
glm::vec3 diff;
|
||||
if (palm.getControllerButtons() & BUTTON_FWD) {
|
||||
if (!_bballIsGrabbed[palm.getSixenseID()]) {
|
||||
// Look for a ball to grab
|
||||
for (int i = 0; i < NUM_BBALLS; i++) {
|
||||
diff = _bballPosition[i] - fingerTipPosition;
|
||||
penetration = glm::length(diff) - (_bballRadius[i] + FINGERTIP_COLLISION_RADIUS);
|
||||
if (penetration < 0.f) {
|
||||
_bballIsGrabbed[palm.getSixenseID()] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_bballIsGrabbed[palm.getSixenseID()]) {
|
||||
// If ball being grabbed, move with finger
|
||||
diff = _bballPosition[_bballIsGrabbed[palm.getSixenseID()]] - fingerTipPosition;
|
||||
penetration = glm::length(diff) - (_bballRadius[_bballIsGrabbed[palm.getSixenseID()]] + FINGERTIP_COLLISION_RADIUS);
|
||||
_bballPosition[_bballIsGrabbed[palm.getSixenseID()]] -= glm::normalize(diff) * penetration;
|
||||
glm::vec3 fingerTipVelocity = _owningAvatar->getOrientation() * palm.getTipVelocity();
|
||||
if (_bballElement[_bballIsGrabbed[palm.getSixenseID()]] != 1) {
|
||||
_bballVelocity[_bballIsGrabbed[palm.getSixenseID()]] = fingerTipVelocity;
|
||||
}
|
||||
_bballPosition[_bballIsGrabbed[palm.getSixenseID()]] = fingerTipPosition;
|
||||
_bballColliding[_bballIsGrabbed[palm.getSixenseID()]] = 1.f;
|
||||
}
|
||||
} else {
|
||||
_bballIsGrabbed[palm.getSixenseID()] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
const float COLLISION_BLEND_RATE = 0.5f;
|
||||
const float ATTRACTION_BLEND_RATE = 0.9f;
|
||||
const float ATTRACTION_VELOCITY_BLEND_RATE = 0.10f;
|
||||
|
||||
void Hand::simulateBuckyBalls(float deltaTime) {
|
||||
// Look for collisions
|
||||
for (int i = 0; i < NUM_BBALLS; i++) {
|
||||
if (_bballElement[i] != 1) {
|
||||
// For 'interacting' elements, look for other balls to interact with
|
||||
for (int j = 0; j < NUM_BBALLS; j++) {
|
||||
if (i != j) {
|
||||
glm::vec3 diff = _bballPosition[i] - _bballPosition[j];
|
||||
float penetration = glm::length(diff) - (_bballRadius[i] + _bballRadius[j]);
|
||||
if (penetration < 0.f) {
|
||||
// Colliding - move away and transfer velocity
|
||||
_bballPosition[i] -= glm::normalize(diff) * penetration * COLLISION_BLEND_RATE;
|
||||
if (glm::dot(_bballVelocity[i], diff) < 0.f) {
|
||||
_bballVelocity[i] = _bballVelocity[i] * (1.f - COLLISION_BLEND_RATE) +
|
||||
glm::reflect(_bballVelocity[i], glm::normalize(diff)) * COLLISION_BLEND_RATE;
|
||||
}
|
||||
}
|
||||
else if ((penetration > EPSILON) && (penetration < BBALLS_ATTRACTION_DISTANCE)) {
|
||||
// If they get close to each other, bring them together with magnetic force
|
||||
_bballPosition[i] -= glm::normalize(diff) * penetration * ATTRACTION_BLEND_RATE;
|
||||
// Also make their velocities more similar
|
||||
_bballVelocity[i] = _bballVelocity[i] * (1.f - ATTRACTION_VELOCITY_BLEND_RATE) + _bballVelocity[j] * ATTRACTION_VELOCITY_BLEND_RATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Update position and bounce on walls
|
||||
const float BBALL_CONTINUOUS_DAMPING = 0.00f;
|
||||
const float BBALL_WALL_COLLISION_DAMPING = 0.2f;
|
||||
|
||||
for (int i = 0; i < NUM_BBALLS; i++) {
|
||||
_bballPosition[i] += _bballVelocity[i] * deltaTime;
|
||||
if (_bballElement[i] != 1) {
|
||||
_bballVelocity[i].y += GRAVITY_BBALLS * deltaTime;
|
||||
}
|
||||
_bballVelocity[i] -= _bballVelocity[i] * BBALL_CONTINUOUS_DAMPING * deltaTime;
|
||||
for (int j = 0; j < 3; j++) {
|
||||
if ((_bballPosition[i][j] + _bballRadius[i]) > (CORNER_BBALLS + RANGE_BBALLS)) {
|
||||
_bballPosition[i][j] = (CORNER_BBALLS + RANGE_BBALLS) - _bballRadius[i];
|
||||
_bballVelocity[i][j] *= -(1.f - BBALL_WALL_COLLISION_DAMPING);
|
||||
}
|
||||
if ((_bballPosition[i][j] - _bballRadius[i]) < (CORNER_BBALLS -RANGE_BBALLS)) {
|
||||
_bballPosition[i][j] = (CORNER_BBALLS -RANGE_BBALLS) + _bballRadius[i];
|
||||
_bballVelocity[i][j] *= -(1.f - BBALL_WALL_COLLISION_DAMPING);
|
||||
}
|
||||
}
|
||||
_bballColliding[i] *= 0.8f;
|
||||
if (_bballColliding[i] < 0.1f) {
|
||||
_bballColliding[i] = 0.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Hand::renderBuckyBalls() {
|
||||
for (int i = 0; i < NUM_BBALLS; i++) {
|
||||
if (_bballColliding[i] > 0.f) {
|
||||
glColor3f(_bballColor[i].x * 1.15f, _bballColor[i].y * 1.15f, _bballColor[i].z * 1.15f);
|
||||
} else {
|
||||
glColor3f(_bballColor[i].x, _bballColor[i].y, _bballColor[i].z);
|
||||
}
|
||||
glPushMatrix();
|
||||
glTranslatef(_bballPosition[i].x, _bballPosition[i].y, _bballPosition[i].z);
|
||||
glutSolidSphere(_bballRadius[i], 15, 15);
|
||||
//glutSolidCube(_bballRadius[i] * 2.f);
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, float deltaTime) {
|
||||
Application* app = Application::getInstance();
|
||||
ParticleTree* particles = app->getParticles()->getTree();
|
||||
|
@ -256,6 +398,10 @@ void Hand::simulate(float deltaTime, bool isMine) {
|
|||
_collisionAge += deltaTime;
|
||||
}
|
||||
|
||||
if (isMine) {
|
||||
simulateBuckyBalls(deltaTime);
|
||||
}
|
||||
|
||||
const glm::vec3 leapHandsOffsetFromFace(0.0, -0.2, -0.3); // place the hand in front of the face where we can see it
|
||||
|
||||
Head& head = _owningAvatar->getHead();
|
||||
|
@ -279,6 +425,7 @@ void Hand::simulate(float deltaTime, bool isMine) {
|
|||
glm::vec3 fingerTipPosition = finger.getTipPosition();
|
||||
|
||||
simulateToyBall(palm, fingerTipPosition, deltaTime);
|
||||
grabBuckyBalls(palm, fingerTipPosition, deltaTime);
|
||||
|
||||
if (palm.getControllerButtons() & BUTTON_4) {
|
||||
_grabDelta += palm.getRawVelocity() * deltaTime;
|
||||
|
@ -453,7 +600,7 @@ void Hand::calculateGeometry() {
|
|||
for (size_t f = 0; f < palm.getNumFingers(); ++f) {
|
||||
FingerData& finger = palm.getFingers()[f];
|
||||
if (finger.isActive()) {
|
||||
const float standardBallRadius = 0.010f;
|
||||
const float standardBallRadius = FINGERTIP_COLLISION_RADIUS;
|
||||
_leapFingerTipBalls.resize(_leapFingerTipBalls.size() + 1);
|
||||
HandBall& ball = _leapFingerTipBalls.back();
|
||||
ball.rotation = _baseOrientation;
|
||||
|
@ -493,6 +640,11 @@ void Hand::calculateGeometry() {
|
|||
void Hand::render(bool isMine) {
|
||||
|
||||
_renderAlpha = 1.0;
|
||||
|
||||
if (isMine) {
|
||||
renderBuckyBalls();
|
||||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::CollisionProxies)) {
|
||||
for (int i = 0; i < getNumPalms(); i++) {
|
||||
PalmData& palm = getPalms()[i];
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
class Avatar;
|
||||
class ProgramObject;
|
||||
|
||||
const int NUM_BBALLS = 200;
|
||||
|
||||
|
||||
class Hand : public HandData {
|
||||
public:
|
||||
|
@ -99,7 +101,10 @@ private:
|
|||
void handleVoxelCollision(PalmData* palm, const glm::vec3& fingerTipPosition, VoxelTreeElement* voxel, float deltaTime);
|
||||
|
||||
void simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, float deltaTime);
|
||||
void grabBuckyBalls(PalmData& palm, const glm::vec3& fingerTipPosition, float deltaTime);
|
||||
|
||||
void simulateBuckyBalls(float deltaTime);
|
||||
void renderBuckyBalls();
|
||||
|
||||
#define MAX_HANDS 2
|
||||
bool _toyBallInHand[MAX_HANDS];
|
||||
|
@ -116,6 +121,15 @@ private:
|
|||
|
||||
AudioInjector _throwInjector;
|
||||
AudioInjector _catchInjector;
|
||||
|
||||
glm::vec3 _bballPosition[NUM_BBALLS];
|
||||
glm::vec3 _bballVelocity[NUM_BBALLS];
|
||||
glm::vec3 _bballColor[NUM_BBALLS];
|
||||
float _bballRadius[NUM_BBALLS];
|
||||
float _bballColliding[NUM_BBALLS];
|
||||
int _bballElement[NUM_BBALLS];
|
||||
int _bballIsGrabbed[2];
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -102,7 +102,7 @@ void SixenseManager::update(float deltaTime) {
|
|||
FingerData finger(palm, &hand);
|
||||
finger.setActive(true);
|
||||
finger.setRawRootPosition(position);
|
||||
const float FINGER_LENGTH = 300.0f; // Millimeters
|
||||
const float FINGER_LENGTH = 150.0f; // Millimeters
|
||||
const glm::vec3 FINGER_VECTOR(0.0f, 0.0f, FINGER_LENGTH);
|
||||
const glm::vec3 newTipPosition = position + rotation * FINGER_VECTOR;
|
||||
finger.setRawTipPosition(position + rotation * FINGER_VECTOR);
|
||||
|
|
Loading…
Reference in a new issue