Support for multiple environments, collisions with notional planet surfaces.

This commit is contained in:
Andrzej Kapolka 2013-05-21 21:33:08 -07:00
parent 8afeeaf222
commit fd98982fa6
15 changed files with 300 additions and 130 deletions

View file

@ -389,7 +389,8 @@ void Application::paintGL() {
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
glm::vec3 relativeSunLoc = glm::normalize(_environment.getSunLocation() - whichCamera.getPosition());
glm::vec3 relativeSunLoc = glm::normalize(_environment.getClosestData(whichCamera.getPosition()).getSunLocation() -
whichCamera.getPosition());
GLfloat light_position0[] = { relativeSunLoc.x, relativeSunLoc.y, relativeSunLoc.z, 0.0 };
glLightfv(GL_LIGHT0, GL_POSITION, light_position0);
GLfloat ambient_color[] = { 0.7, 0.7, 0.8 };
@ -829,26 +830,6 @@ static glm::vec3 getFaceVector(BoxFace face) {
}
}
//Find and return the gravity vector at this location
static glm::vec3 getGravity(const glm::vec3& pos) {
//
// For now, we'll test this with a simple global lookup, but soon we will add getting this
// from the domain/voxelserver (or something similar)
//
if ((pos.x > 0.f) &&
(pos.x < 10.f) &&
(pos.z > 0.f) &&
(pos.z < 10.f) &&
(pos.y > 0.f) &&
(pos.y < 3.f)) {
// If above ground plane, turn gravity on
return glm::vec3(0.f, -1.f, 0.f);
} else {
// If flying in space, turn gravity OFF
return glm::vec3(0.f, 0.f, 0.f);
}
}
void Application::idle() {
timeval check;
gettimeofday(&check, NULL);
@ -983,7 +964,7 @@ void Application::idle() {
agentList->unlock();
// Simulate myself
_myAvatar.setGravity(getGravity(_myAvatar.getPosition()));
_myAvatar.setGravity(_environment.getGravity(_myAvatar.getPosition()));
if (_transmitterDrives->isChecked() && _myTransmitter.isConnected()) {
_myAvatar.simulate(deltaTime, &_myTransmitter);
} else {
@ -1653,13 +1634,14 @@ void Application::displaySide(Camera& whichCamera) {
// compute starfield alpha based on distance from atmosphere
float alpha = 1.0f;
if (_renderAtmosphereOn->isChecked()) {
float height = glm::distance(whichCamera.getPosition(), _environment.getAtmosphereCenter());
if (height < _environment.getAtmosphereInnerRadius()) {
const EnvironmentData& closestData = _environment.getClosestData(whichCamera.getPosition());
float height = glm::distance(whichCamera.getPosition(), closestData.getAtmosphereCenter());
if (height < closestData.getAtmosphereInnerRadius()) {
alpha = 0.0f;
} else if (height < _environment.getAtmosphereOuterRadius()) {
alpha = (height - _environment.getAtmosphereInnerRadius()) /
(_environment.getAtmosphereOuterRadius() - _environment.getAtmosphereInnerRadius());
} else if (height < closestData.getAtmosphereOuterRadius()) {
alpha = (height - closestData.getAtmosphereInnerRadius()) /
(closestData.getAtmosphereOuterRadius() - closestData.getAtmosphereInnerRadius());
}
}
@ -1669,7 +1651,7 @@ void Application::displaySide(Camera& whichCamera) {
// draw the sky dome
if (_renderAtmosphereOn->isChecked()) {
_environment.renderAtmosphere(whichCamera);
_environment.renderAtmospheres(whichCamera);
}
glEnable(GL_LIGHTING);
@ -2142,7 +2124,7 @@ void* Application::networkReceive(void* args) {
app->_voxels.parseData(app->_incomingPacket, bytesReceived);
break;
case PACKET_HEADER_ENVIRONMENT_DATA:
app->_environment.parseData(app->_incomingPacket, bytesReceived);
app->_environment.parseData(&senderAddress, app->_incomingPacket, bytesReceived);
break;
case PACKET_HEADER_BULK_AVATAR_DATA:
AgentList::getInstance()->processBulkAgentData(&senderAddress,

View file

@ -63,6 +63,7 @@ public:
Avatar* getAvatar() { return &_myAvatar; }
VoxelSystem* getVoxels() { return &_voxels; }
Environment* getEnvironment() { return &_environment; }
private slots:

View file

@ -239,12 +239,9 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
// apply gravity and collision with the ground/floor
if (_isMine && USING_AVATAR_GRAVITY) {
if (_position.y > _pelvisStandingHeight + 0.01f) {
_velocity += _gravity * (GRAVITY_SCALE * deltaTime);
} else if (_position.y < _pelvisStandingHeight) {
_position.y = _pelvisStandingHeight;
_velocity.y = -_velocity.y * BOUNCE;
}
_velocity += _gravity * (GRAVITY_SCALE * deltaTime);
updateCollisionWithEnvironment(deltaTime);
}
// update body springs
@ -589,20 +586,34 @@ void Avatar::updateCollisionWithSphere(glm::vec3 position, float radius, float d
}
}
void Avatar::updateCollisionWithVoxels(float deltaTime) {
VoxelSystem* voxels = Application::getInstance()->getVoxels();
void Avatar::updateCollisionWithEnvironment(float deltaTime) {
float radius = _height * 0.125f;
glm::vec3 halfVector = glm::vec3(0.0f, _height * ONE_HALF - radius, 0.0f);
glm::vec3 penetration;
if (voxels->findCapsulePenetration(_position - halfVector, _position + halfVector, radius, penetration)) {
_position += penetration;
// reflect the velocity component in the direction of penetration
glm::vec3 direction = glm::normalize(penetration);
_velocity -= 2.0f * glm::dot(_velocity, direction) * direction * BOUNCE;
if (Application::getInstance()->getEnvironment()->findCapsulePenetration(
_position - halfVector, _position + halfVector, radius, penetration)) {
applyCollisionWithScene(penetration, deltaTime);
}
}
void Avatar::updateCollisionWithVoxels(float deltaTime) {
float radius = _height * 0.125f;
glm::vec3 halfVector = glm::vec3(0.0f, _height * ONE_HALF - radius, 0.0f);
glm::vec3 penetration;
if (Application::getInstance()->getVoxels()->findCapsulePenetration(
_position - halfVector, _position + halfVector, radius, penetration)) {
applyCollisionWithScene(penetration, deltaTime);
}
}
void Avatar::applyCollisionWithScene(const glm::vec3& penetration, float deltaTime) {
_position += penetration;
// reflect the velocity component in the direction of penetration
glm::vec3 direction = glm::normalize(penetration);
//_velocity -= 2.0f * glm::dot(_velocity, direction) * direction * BOUNCE;
}
void Avatar::updateAvatarCollisions(float deltaTime) {
// Reset detector for nearest avatar

View file

@ -194,7 +194,9 @@ private:
void updateHandMovementAndTouching(float deltaTime);
void updateAvatarCollisions(float deltaTime);
void updateCollisionWithSphere( glm::vec3 position, float radius, float deltaTime );
void updateCollisionWithEnvironment(float deltaTime);
void updateCollisionWithVoxels(float deltaTime);
void applyCollisionWithScene(const glm::vec3& penetration, float deltaTime);
void applyCollisionWithOtherAvatar( Avatar * other, float deltaTime );
void setHeadFromGyros(glm::vec3 * eulerAngles, glm::vec3 * angularVelocity, float deltaTime, float smoothingTime);
void checkForMouseRayTouching();

View file

@ -6,7 +6,9 @@
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
#include <QByteArray>
#include <QtDebug>
#include <GeometryUtil.h>
#include <SharedUtil.h>
#include "Camera.h"
@ -14,64 +16,94 @@
#include "renderer/ProgramObject.h"
#include "world.h"
uint qHash(const sockaddr& address) {
const sockaddr_in* inetAddress = reinterpret_cast<const sockaddr_in*>(&address);
if (inetAddress->sin_family != AF_INET) {
return 0; // shouldn't happen, but if it does, zero is a perfectly valid hash
}
return inetAddress->sin_port + qHash(QByteArray::fromRawData(
reinterpret_cast<const char*>(&inetAddress->sin_addr), sizeof(in_addr)));
}
bool operator== (const sockaddr& addr1, const sockaddr& addr2) {
return socketMatch(&addr1, &addr2);
}
void Environment::init() {
switchToResourcesParentIfRequired();
_skyFromAtmosphereProgram = createSkyProgram("Atmosphere", _skyFromAtmosphereUniformLocations);
_skyFromSpaceProgram = createSkyProgram("Space", _skyFromSpaceUniformLocations);
// start off with a default-constructed environment data
_data[sockaddr()][0];
}
void Environment::renderAtmosphere(Camera& camera) {
glPushMatrix();
glTranslatef(getAtmosphereCenter().x, getAtmosphereCenter().y, getAtmosphereCenter().z);
glm::vec3 relativeCameraPos = camera.getPosition() - getAtmosphereCenter();
float height = glm::length(relativeCameraPos);
// use the appropriate shader depending on whether we're inside or outside
ProgramObject* program;
int* locations;
if (height < getAtmosphereOuterRadius()) {
program = _skyFromAtmosphereProgram;
locations = _skyFromAtmosphereUniformLocations;
} else {
program = _skyFromSpaceProgram;
locations = _skyFromSpaceUniformLocations;
void Environment::renderAtmospheres(Camera& camera) {
foreach (const ServerData& serverData, _data) {
foreach (const EnvironmentData& environmentData, serverData) {
renderAtmosphere(camera, environmentData);
}
}
}
glm::vec3 Environment::getGravity (const glm::vec3& position) const {
glm::vec3 gravity;
foreach (const ServerData& serverData, _data) {
foreach (const EnvironmentData& environmentData, serverData) {
glm::vec3 vector = environmentData.getAtmosphereCenter() - position;
if (glm::length(vector) < environmentData.getAtmosphereOuterRadius()) {
gravity += glm::normalize(vector) * environmentData.getGravity();
}
}
}
return gravity;
}
const EnvironmentData& Environment::getClosestData(const glm::vec3& position) const {
const EnvironmentData* closest;
float closestDistance = FLT_MAX;
foreach (const ServerData& serverData, _data) {
foreach (const EnvironmentData& environmentData, serverData) {
float distance = glm::distance(position, environmentData.getAtmosphereCenter()) -
environmentData.getAtmosphereOuterRadius();
if (distance < closestDistance) {
closest = &environmentData;
closestDistance = distance;
}
}
}
return *closest;
}
bool Environment::findCapsulePenetration(const glm::vec3& start, const glm::vec3& end,
float radius, glm::vec3& penetration) const {
bool found = false;
penetration = glm::vec3(0.0f, 0.0f, 0.0f);
foreach (const ServerData& serverData, _data) {
foreach (const EnvironmentData& environmentData, serverData) {
glm::vec3 vector = computeVectorFromPointToSegment(environmentData.getAtmosphereCenter(), start, end);
float vectorLength = glm::length(vector);
float distance = vectorLength - environmentData.getAtmosphereInnerRadius() - radius;
if (distance < 0.0f) {
penetration += vector * (-distance / vectorLength);
found = true;
}
}
}
return found;
}
int Environment::parseData(sockaddr *senderAddress, unsigned char* sourceBuffer, int numBytes) {
EnvironmentData newData;
int bytesRead = newData.parseData(sourceBuffer, numBytes);
// the constants here are from Sean O'Neil's GPU Gems entry
// (http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html), GameEngine.cpp
program->bind();
program->setUniform(locations[CAMERA_POS_LOCATION], relativeCameraPos);
glm::vec3 lightDirection = glm::normalize(getSunLocation());
program->setUniform(locations[LIGHT_POS_LOCATION], lightDirection);
program->setUniformValue(locations[INV_WAVELENGTH_LOCATION],
1 / powf(getScatteringWavelengths().r, 4.0f),
1 / powf(getScatteringWavelengths().g, 4.0f),
1 / powf(getScatteringWavelengths().b, 4.0f));
program->setUniformValue(locations[CAMERA_HEIGHT2_LOCATION], height * height);
program->setUniformValue(locations[OUTER_RADIUS_LOCATION], getAtmosphereOuterRadius());
program->setUniformValue(locations[OUTER_RADIUS2_LOCATION], getAtmosphereOuterRadius() * getAtmosphereOuterRadius());
program->setUniformValue(locations[INNER_RADIUS_LOCATION], getAtmosphereInnerRadius());
program->setUniformValue(locations[KR_ESUN_LOCATION], getRayleighScattering() * getSunBrightness());
program->setUniformValue(locations[KM_ESUN_LOCATION], getMieScattering() * getSunBrightness());
program->setUniformValue(locations[KR_4PI_LOCATION], getRayleighScattering() * 4.0f * PIf);
program->setUniformValue(locations[KM_4PI_LOCATION], getMieScattering() * 4.0f * PIf);
program->setUniformValue(locations[SCALE_LOCATION], 1.0f / (getAtmosphereOuterRadius() - getAtmosphereInnerRadius()));
program->setUniformValue(locations[SCALE_DEPTH_LOCATION], 0.25f);
program->setUniformValue(locations[SCALE_OVER_SCALE_DEPTH_LOCATION],
(1.0f / (getAtmosphereOuterRadius() - getAtmosphereInnerRadius())) / 0.25f);
program->setUniformValue(locations[G_LOCATION], -0.990f);
program->setUniformValue(locations[G2_LOCATION], -0.990f * -0.990f);
// update the mapping by address/ID
_data[*senderAddress][newData.getID()] = newData;
glDepthMask(GL_FALSE);
glDisable(GL_DEPTH_TEST);
glutSolidSphere(getAtmosphereOuterRadius(), 100, 50);
glDepthMask(GL_TRUE);
// remove the default mapping, if any
_data.remove(sockaddr());
program->release();
glPopMatrix();
return bytesRead;
}
ProgramObject* Environment::createSkyProgram(const char* from, int* locations) {
@ -100,3 +132,57 @@ ProgramObject* Environment::createSkyProgram(const char* from, int* locations) {
return program;
}
void Environment::renderAtmosphere(Camera& camera, const EnvironmentData& data) {
glPushMatrix();
glTranslatef(data.getAtmosphereCenter().x, data.getAtmosphereCenter().y, data.getAtmosphereCenter().z);
glm::vec3 relativeCameraPos = camera.getPosition() - data.getAtmosphereCenter();
float height = glm::length(relativeCameraPos);
// use the appropriate shader depending on whether we're inside or outside
ProgramObject* program;
int* locations;
if (height < data.getAtmosphereOuterRadius()) {
program = _skyFromAtmosphereProgram;
locations = _skyFromAtmosphereUniformLocations;
} else {
program = _skyFromSpaceProgram;
locations = _skyFromSpaceUniformLocations;
}
// the constants here are from Sean O'Neil's GPU Gems entry
// (http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html), GameEngine.cpp
program->bind();
program->setUniform(locations[CAMERA_POS_LOCATION], relativeCameraPos);
glm::vec3 lightDirection = glm::normalize(data.getSunLocation());
program->setUniform(locations[LIGHT_POS_LOCATION], lightDirection);
program->setUniformValue(locations[INV_WAVELENGTH_LOCATION],
1 / powf(data.getScatteringWavelengths().r, 4.0f),
1 / powf(data.getScatteringWavelengths().g, 4.0f),
1 / powf(data.getScatteringWavelengths().b, 4.0f));
program->setUniformValue(locations[CAMERA_HEIGHT2_LOCATION], height * height);
program->setUniformValue(locations[OUTER_RADIUS_LOCATION], data.getAtmosphereOuterRadius());
program->setUniformValue(locations[OUTER_RADIUS2_LOCATION], data.getAtmosphereOuterRadius() * data.getAtmosphereOuterRadius());
program->setUniformValue(locations[INNER_RADIUS_LOCATION], data.getAtmosphereInnerRadius());
program->setUniformValue(locations[KR_ESUN_LOCATION], data.getRayleighScattering() * data.getSunBrightness());
program->setUniformValue(locations[KM_ESUN_LOCATION], data.getMieScattering() * data.getSunBrightness());
program->setUniformValue(locations[KR_4PI_LOCATION], data.getRayleighScattering() * 4.0f * PIf);
program->setUniformValue(locations[KM_4PI_LOCATION], data.getMieScattering() * 4.0f * PIf);
program->setUniformValue(locations[SCALE_LOCATION], 1.0f / (data.getAtmosphereOuterRadius() - data.getAtmosphereInnerRadius()));
program->setUniformValue(locations[SCALE_DEPTH_LOCATION], 0.25f);
program->setUniformValue(locations[SCALE_OVER_SCALE_DEPTH_LOCATION],
(1.0f / (data.getAtmosphereOuterRadius() - data.getAtmosphereInnerRadius())) / 0.25f);
program->setUniformValue(locations[G_LOCATION], -0.990f);
program->setUniformValue(locations[G2_LOCATION], -0.990f * -0.990f);
glDepthMask(GL_FALSE);
glDisable(GL_DEPTH_TEST);
glutSolidSphere(data.getAtmosphereOuterRadius(), 100, 50);
glDepthMask(GL_TRUE);
program->release();
glPopMatrix();
}

View file

@ -9,22 +9,35 @@
#ifndef __interface__Environment__
#define __interface__Environment__
#include <QHash>
#include <UDPSocket.h>
#include "EnvironmentData.h"
#include "InterfaceConfig.h"
class Camera;
class ProgramObject;
class Environment : public EnvironmentData {
class Environment {
public:
void init();
void renderAtmosphere(Camera& camera);
void renderAtmospheres(Camera& camera);
glm::vec3 getGravity (const glm::vec3& position) const;
const EnvironmentData& getClosestData(const glm::vec3& position) const;
bool findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration) const;
int parseData(sockaddr *senderAddress, unsigned char* sourceBuffer, int numBytes);
private:
ProgramObject* createSkyProgram(const char* from, int* locations);
void renderAtmosphere(Camera& camera, const EnvironmentData& data);
ProgramObject* _skyFromAtmosphereProgram;
ProgramObject* _skyFromSpaceProgram;
@ -50,6 +63,10 @@ private:
int _skyFromAtmosphereUniformLocations[LOCATION_COUNT];
int _skyFromSpaceUniformLocations[LOCATION_COUNT];
typedef QHash<int, EnvironmentData> ServerData;
QHash<sockaddr, ServerData> _data;
};
#endif /* defined(__interface__Environment__) */

View file

@ -1,5 +1,8 @@
cmake_minimum_required(VERSION 2.8)
set(ROOT_DIR ../..)
set(MACRO_DIR ${ROOT_DIR}/cmake/macros)
set(TARGET_NAME shared)
project(${TARGET_NAME})
@ -12,6 +15,9 @@ set(HIFI_SHARED_LIBRARY ${TARGET_NAME})
set(EXTERNAL_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external)
include(${MACRO_DIR}/IncludeGLM.cmake)
include_glm(${TARGET_NAME} ${ROOT_DIR})
if (WIN32)
# include headers for external libraries and InterfaceConfig.
include_directories(${EXTERNAL_ROOT_DIR})
@ -25,4 +31,4 @@ endif (WIN32)
if (UNIX AND NOT APPLE)
find_package(Threads REQUIRED)
target_link_libraries(${TARGET_NAME} ${CMAKE_THREAD_LIBS_INIT})
endif (UNIX AND NOT APPLE)
endif (UNIX AND NOT APPLE)

View file

@ -27,7 +27,7 @@ using shared_lib::printLog;
sockaddr_in destSockaddr, senderAddress;
bool socketMatch(sockaddr* first, sockaddr* second) {
bool socketMatch(const sockaddr* first, const sockaddr* second) {
if (first != NULL && second != NULL) {
// utility function that indicates if two sockets are equivalent
@ -38,8 +38,8 @@ bool socketMatch(sockaddr* first, sockaddr* second) {
// not the same family, can't be equal
return false;
} else if (first->sa_family == AF_INET) {
sockaddr_in *firstIn = (sockaddr_in *) first;
sockaddr_in *secondIn = (sockaddr_in *) second;
const sockaddr_in *firstIn = (const sockaddr_in *) first;
const sockaddr_in *secondIn = (const sockaddr_in *) second;
return firstIn->sin_addr.s_addr == secondIn->sin_addr.s_addr
&& firstIn->sin_port == secondIn->sin_port;

View file

@ -34,7 +34,7 @@ private:
bool blocking;
};
bool socketMatch(sockaddr* first, sockaddr* second);
bool socketMatch(const sockaddr* first, const sockaddr* second);
int packSocket(unsigned char* packStore, in_addr_t inAddress, in_port_t networkOrderPort);
int packSocket(unsigned char* packStore, sockaddr* socketToPack);
int unpackSocket(unsigned char* packedData, sockaddr* unpackDestSocket);

View file

@ -11,8 +11,10 @@
#include "PacketHeaders.h"
// initial values from Sean O'Neil's GPU Gems entry (http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html),
// GameEngine.cpp (and the radius of the earth)
EnvironmentData::EnvironmentData() :
// GameEngine.cpp
EnvironmentData::EnvironmentData(int id) :
_id(id),
_gravity(1.0f),
_atmosphereCenter(0, -1000, 0),
_atmosphereInnerRadius(1000),
_atmosphereOuterRadius(1025),
@ -27,7 +29,13 @@ int EnvironmentData::getBroadcastData(unsigned char* destinationBuffer) const {
unsigned char* bufferStart = destinationBuffer;
*destinationBuffer++ = PACKET_HEADER_ENVIRONMENT_DATA;
memcpy(destinationBuffer, &_id, sizeof(_id));
destinationBuffer += sizeof(_id);
memcpy(destinationBuffer, &_gravity, sizeof(_gravity));
destinationBuffer += sizeof(_gravity);
memcpy(destinationBuffer, &_atmosphereCenter, sizeof(_atmosphereCenter));
destinationBuffer += sizeof(_atmosphereCenter);
@ -61,6 +69,12 @@ int EnvironmentData::parseData(unsigned char* sourceBuffer, int numBytes) {
unsigned char* startPosition = sourceBuffer;
memcpy(&_id, sourceBuffer, sizeof(_id));
sourceBuffer += sizeof(_id);
memcpy(&_gravity, sourceBuffer, sizeof(_gravity));
sourceBuffer += sizeof(_gravity);
memcpy(&_atmosphereCenter, sourceBuffer, sizeof(_atmosphereCenter));
sourceBuffer += sizeof(_atmosphereCenter);

View file

@ -14,7 +14,13 @@
class EnvironmentData {
public:
EnvironmentData();
EnvironmentData(int id = 0);
void setID(int id) { _id = id; }
int getID() const { return _id; }
void setGravity(float gravity) { _gravity = gravity; }
float getGravity() const { return _gravity; }
void setAtmosphereCenter(const glm::vec3& center) { _atmosphereCenter = center; }
void setAtmosphereInnerRadius(float radius) { _atmosphereInnerRadius = radius; }
@ -41,6 +47,10 @@ public:
private:
int _id;
float _gravity;
glm::vec3 _atmosphereCenter;
float _atmosphereInnerRadius;
float _atmosphereOuterRadius;

View file

@ -0,0 +1,23 @@
//
// GeometryUtil.cpp
// interface
//
// Created by Andrzej Kapolka on 5/21/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
#include "GeometryUtil.h"
glm::vec3 computeVectorFromPointToSegment(const glm::vec3& point, const glm::vec3& start, const glm::vec3& end) {
// compute the projection of the point vector onto the segment vector
glm::vec3 segmentVector = end - start;
float proj = glm::dot(point - start, segmentVector) / glm::dot(segmentVector, segmentVector);
if (proj <= 0.0f) { // closest to the start
return start - point;
} else if (proj >= 1.0f) { // closest to the end
return end - point;
} else { // closest to the middle
return start + segmentVector*proj - point;
}
}

View file

@ -0,0 +1,16 @@
//
// GeometryUtil.h
// interface
//
// Created by Andrzej Kapolka on 5/21/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#ifndef __interface__GeometryUtil__
#define __interface__GeometryUtil__
#include <glm/glm.hpp>
glm::vec3 computeVectorFromPointToSegment(const glm::vec3& point, const glm::vec3& start, const glm::vec3& end);
#endif /* defined(__interface__GeometryUtil__) */

View file

@ -16,6 +16,7 @@
#include "voxels_Log.h"
#include "PacketHeaders.h"
#include "OctalCode.h"
#include "GeometryUtil.h"
#include "VoxelTree.h"
#include "VoxelNodeBag.h"
#include "ViewFrustum.h"
@ -725,21 +726,6 @@ public:
bool found;
};
glm::vec3 computeVectorFromPointToSegment(const glm::vec3& point, const glm::vec3& start, const glm::vec3& end) {
// compute the projection of the point vector onto the segment vector
glm::vec3 segmentVector = end - start;
float proj = glm::dot(point - start, segmentVector) / glm::dot(segmentVector, segmentVector);
if (proj <= 0.0f) { // closest to the start
return start - point;
} else if (proj >= 1.0f) { // closest to the end
return end - point;
} else { // closest to the middle
return start + segmentVector*proj - point;
}
}
bool findCapsulePenetrationOp(VoxelNode* node, void* extraData) {
CapsuleArgs* args = static_cast<CapsuleArgs*>(extraData);

View file

@ -60,7 +60,7 @@ bool shouldShowAnimationDebug = false;
EnvironmentData environmentData;
EnvironmentData environmentData[3];
void randomlyFillVoxelTree(int levelsToGo, VoxelNode *currentRootNode) {
@ -162,7 +162,8 @@ void resInVoxelDistributor(AgentList* agentList,
int trueBytesSent = 0;
double start = usecTimestampNow();
while (packetsSentThisInterval < PACKETS_PER_CLIENT_PER_INTERVAL - 1) {
int environmentPacketCount = sizeof(environmentData) / sizeof(environmentData[0]);
while (packetsSentThisInterval < PACKETS_PER_CLIENT_PER_INTERVAL - environmentPacketCount) {
if (!agentData->nodeBag.isEmpty()) {
VoxelNode* subTree = agentData->nodeBag.extract();
bytesWritten = randomTree.encodeTreeBitstream(agentData->getMaxSearchLevel(), subTree,
@ -193,11 +194,13 @@ void resInVoxelDistributor(AgentList* agentList,
packetsSentThisInterval = PACKETS_PER_CLIENT_PER_INTERVAL; // done for now, no nodes left
}
}
// send the environment packet
int envPacketLength = environmentData.getBroadcastData(tempOutputBuffer);
agentList->getAgentSocket()->send(agent->getActiveSocket(), tempOutputBuffer, envPacketLength);
trueBytesSent += envPacketLength;
truePacketsSent++;
// send the environment packets
for (int i = 0; i < environmentPacketCount; i++) {
int envPacketLength = environmentData[i].getBroadcastData(tempOutputBuffer);
agentList->getAgentSocket()->send(agent->getActiveSocket(), tempOutputBuffer, envPacketLength);
trueBytesSent += envPacketLength;
truePacketsSent++;
}
double end = usecTimestampNow();
double elapsedmsec = (end - start)/1000.0;
@ -282,7 +285,8 @@ void deepestLevelVoxelDistributor(AgentList* agentList,
int trueBytesSent = 0;
double start = usecTimestampNow();
while (packetsSentThisInterval < PACKETS_PER_CLIENT_PER_INTERVAL - 1) {
int environmentPacketCount = sizeof(environmentData) / sizeof(environmentData[0]);
while (packetsSentThisInterval < PACKETS_PER_CLIENT_PER_INTERVAL - environmentPacketCount) {
if (!agentData->nodeBag.isEmpty()) {
VoxelNode* subTree = agentData->nodeBag.extract();
bytesWritten = randomTree.encodeTreeBitstream(INT_MAX, subTree,
@ -313,11 +317,13 @@ void deepestLevelVoxelDistributor(AgentList* agentList,
packetsSentThisInterval = PACKETS_PER_CLIENT_PER_INTERVAL; // done for now, no nodes left
}
}
// send the environment packet
int envPacketLength = environmentData.getBroadcastData(tempOutputBuffer);
agentList->getAgentSocket()->send(agent->getActiveSocket(), tempOutputBuffer, envPacketLength);
trueBytesSent += envPacketLength;
truePacketsSent++;
// send the environment packets
for (int i = 0; i < environmentPacketCount; i++) {
int envPacketLength = environmentData[i].getBroadcastData(tempOutputBuffer);
agentList->getAgentSocket()->send(agent->getActiveSocket(), tempOutputBuffer, envPacketLength);
trueBytesSent += envPacketLength;
truePacketsSent++;
}
double end = usecTimestampNow();
double elapsedmsec = (end - start)/1000.0;
@ -517,6 +523,16 @@ int main(int argc, const char * argv[])
addSphereScene(&randomTree);
}
// for now, initialize the environments with fixed values
environmentData[1].setID(1);
environmentData[1].setAtmosphereCenter(glm::vec3(0.5, 0.5, (0.25 - 0.06125)) * (float)TREE_SCALE);
environmentData[1].setAtmosphereInnerRadius(0.030625f * TREE_SCALE);
environmentData[1].setAtmosphereOuterRadius(0.030625f * TREE_SCALE * 1.025f);
environmentData[2].setID(2);
environmentData[2].setAtmosphereCenter(glm::vec3(0.5f, 0.5f, 0.5f) * (float)TREE_SCALE);
environmentData[2].setAtmosphereInnerRadius(0.1875f * TREE_SCALE);
environmentData[2].setAtmosphereOuterRadius(0.1875f * TREE_SCALE * 1.025f);
pthread_t sendVoxelThread;
pthread_create(&sendVoxelThread, NULL, distributeVoxelsToListeners, NULL);