Showing the changes to interface/src/MetavoxelSystem.cpp (1 of 9 files). Show all
Unified · Split
| @@ -35,6 +35,8 @@ MetavoxelSystem::MetavoxelSystem() : · 34 unmodified lines | |||
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | void MetavoxelSystem::init() { | 37 | void MetavoxelSystem::init() { |
| 38 | MetavoxelClientManager::init(); | ||
| 39 | |||
| 38 | if (!_program.isLinked()) { | 40 | if (!_program.isLinked()) { |
| 39 | _program.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/metavoxel_point.vert"); | 41 | _program.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/metavoxel_point.vert"); |
| 40 | _program.link(); | 42 | _program.link(); |
| @@ -43,62 +45,19 @@ void MetavoxelSystem::init() { · 2 unmodified lines | |||
| 43 | } | 45 | } |
| 44 | _buffer.setUsagePattern(QOpenGLBuffer::DynamicDraw); | 46 | _buffer.setUsagePattern(QOpenGLBuffer::DynamicDraw); |
| 45 | _buffer.create(); | 47 | _buffer.create(); |
| 46 | |||
| 47 | connect(NodeList::getInstance(), SIGNAL(nodeAdded(SharedNodePointer)), SLOT(maybeAttachClient(const SharedNodePointer&))); | ||
| 48 | } | ||
| 49 | |||
| 50 | SharedObjectPointer MetavoxelSystem::findFirstRaySpannerIntersection( | ||
| 51 | const glm::vec3& origin, const glm::vec3& direction, const AttributePointer& attribute, float& distance) { | ||
| 52 | SharedObjectPointer closestSpanner; | ||
| 53 | float closestDistance = FLT_MAX; | ||
| 54 | foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { | ||
| 55 | if (node->getType() == NodeType::MetavoxelServer) { | ||
| 56 | QMutexLocker locker(&node->getMutex()); | ||
| 57 | MetavoxelSystemClient* client = static_cast<MetavoxelSystemClient*>(node->getLinkedData()); | ||
| 58 | if (client) { | ||
| 59 | float clientDistance; | ||
| 60 | SharedObjectPointer clientSpanner = client->getData().findFirstRaySpannerIntersection( | ||
| 61 | origin, direction, attribute, clientDistance); | ||
| 62 | if (clientSpanner && clientDistance < closestDistance) { | ||
| 63 | closestSpanner = clientSpanner; | ||
| 64 | closestDistance = clientDistance; | ||
| 65 | } | ||
| 66 | } | ||
| 67 | } | ||
| 68 | } | ||
| 69 | if (closestSpanner) { | ||
| 70 | distance = closestDistance; | ||
| 71 | } | ||
| 72 | return closestSpanner; | ||
| 73 | } | 48 | } |
| 74 | 49 | ||
| 75 | void MetavoxelSystem::applyEdit(const MetavoxelEditMessage& edit, bool reliable) { | 50 | MetavoxelLOD MetavoxelSystem::getLOD() const { |
| 76 | foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { | 51 | const float FIXED_LOD_THRESHOLD = 0.01f; |
| 77 | if (node->getType() == NodeType::MetavoxelServer) { | 52 | return MetavoxelLOD(Application::getInstance()->getCamera()->getPosition(), FIXED_LOD_THRESHOLD); |
| 78 | QMutexLocker locker(&node->getMutex()); | ||
| 79 | MetavoxelSystemClient* client = static_cast<MetavoxelSystemClient*>(node->getLinkedData()); | ||
| 80 | if (client) { | ||
| 81 | client->applyEdit(edit, reliable); | ||
| 82 | } | ||
| 83 | } | ||
| 84 | } | ||
| 85 | } | 53 | } |
| 86 | 54 | ||
| 87 | void MetavoxelSystem::simulate(float deltaTime) { | 55 | void MetavoxelSystem::simulate(float deltaTime) { |
| 88 | // simulate the clients | 56 | // update the clients |
| 89 | _points.clear(); | 57 | _points.clear(); |
| 90 | _simulateVisitor.setDeltaTime(deltaTime); | 58 | _simulateVisitor.setDeltaTime(deltaTime); |
| 91 | _simulateVisitor.setOrder(-Application::getInstance()->getViewFrustum()->getDirection()); | 59 | _simulateVisitor.setOrder(-Application::getInstance()->getViewFrustum()->getDirection()); |
| 92 | foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { | 60 | update(); |
| 93 | if (node->getType() == NodeType::MetavoxelServer) { | ||
| 94 | QMutexLocker locker(&node->getMutex()); | ||
| 95 | MetavoxelSystemClient* client = static_cast<MetavoxelSystemClient*>(node->getLinkedData()); | ||
| 96 | if (client) { | ||
| 97 | client->simulate(deltaTime); | ||
| 98 | client->guide(_simulateVisitor); | ||
| 99 | } | ||
| 100 | } | ||
| 101 | } | ||
| 102 | 61 | ||
| 103 | _buffer.bind(); | 62 | _buffer.bind(); |
| 104 | int bytes = _points.size() * sizeof(Point); | 63 | int bytes = _points.size() * sizeof(Point); |
| @@ -161,11 +120,13 @@ void MetavoxelSystem::render() { · 56 unmodified lines | |||
| 161 | } | 120 | } |
| 162 | } | 121 | } |
| 163 | 122 | ||
| 164 | void MetavoxelSystem::maybeAttachClient(const SharedNodePointer& node) { | 123 | MetavoxelClient* MetavoxelSystem::createClient(const SharedNodePointer& node) { |
| 165 | if (node->getType() == NodeType::MetavoxelServer) { | 124 | return new MetavoxelSystemClient(node, this); |
| 166 | QMutexLocker locker(&node->getMutex()); | 125 | } |
| 167 | node->setLinkedData(new MetavoxelSystemClient(NodeList::getInstance()->nodeWithUUID(node->getUUID()))); | 126 | |
| 168 | } | 127 | void MetavoxelSystem::updateClient(MetavoxelClient* client) { |
| 128 | MetavoxelClientManager::updateClient(client); | ||
| 129 | client->guide(_simulateVisitor); | ||
| 169 | } | 130 | } |
| 170 | 131 | ||
| 171 | MetavoxelSystem::SimulateVisitor::SimulateVisitor(QVector<Point>& points) : | 132 | MetavoxelSystem::SimulateVisitor::SimulateVisitor(QVector<Point>& points) : |
| @@ -235,64 +196,8 @@ bool MetavoxelSystem::RenderVisitor::visit(Spanner* spanner, const glm::vec3& cl · 63 unmodified lines | |||
| 235 | return true; | 196 | return true; |
| 236 | } | 197 | } |
| 237 | 198 | ||
| 238 | MetavoxelSystemClient::MetavoxelSystemClient(const SharedNodePointer& node) : | 199 | MetavoxelSystemClient::MetavoxelSystemClient(const SharedNodePointer& node, MetavoxelSystem* system) : |
| 239 | _node(node), | 200 | MetavoxelClient(node, system) { |
| 240 | _sequencer(byteArrayWithPopulatedHeader(PacketTypeMetavoxelData)) { | ||
| 241 | |||
| 242 | connect(&_sequencer, SIGNAL(readyToWrite(const QByteArray&)), SLOT(sendData(const QByteArray&))); | ||
| 243 | connect(&_sequencer, SIGNAL(readyToRead(Bitstream&)), SLOT(readPacket(Bitstream&))); | ||
| 244 | connect(&_sequencer, SIGNAL(sendAcknowledged(int)), SLOT(clearSendRecordsBefore(int))); | ||
| 245 | connect(&_sequencer, SIGNAL(receiveAcknowledged(int)), SLOT(clearReceiveRecordsBefore(int))); | ||
| 246 | |||
| 247 | // insert the baseline send record | ||
| 248 | SendRecord sendRecord = { 0 }; | ||
| 249 | _sendRecords.append(sendRecord); | ||
| 250 | |||
| 251 | // insert the baseline receive record | ||
| 252 | ReceiveRecord receiveRecord = { 0, _data }; | ||
| 253 | _receiveRecords.append(receiveRecord); | ||
| 254 | } | ||
| 255 | |||
| 256 | MetavoxelSystemClient::~MetavoxelSystemClient() { | ||
| 257 | // close the session | ||
| 258 | Bitstream& out = _sequencer.startPacket(); | ||
| 259 | out << QVariant::fromValue(CloseSessionMessage()); | ||
| 260 | _sequencer.endPacket(); | ||
| 261 | } | ||
| 262 | |||
| 263 | static MetavoxelLOD getLOD() { | ||
| 264 | const float FIXED_LOD_THRESHOLD = 0.01f; | ||
| 265 | return MetavoxelLOD(Application::getInstance()->getCamera()->getPosition(), FIXED_LOD_THRESHOLD); | ||
| 266 | } | ||
| 267 | |||
| 268 | void MetavoxelSystemClient::guide(MetavoxelVisitor& visitor) { | ||
| 269 | visitor.setLOD(getLOD()); | ||
| 270 | _data.guide(visitor); | ||
| 271 | } | ||
| 272 | |||
| 273 | void MetavoxelSystemClient::applyEdit(const MetavoxelEditMessage& edit, bool reliable) { | ||
| 274 | if (reliable) { | ||
| 275 | _sequencer.getReliableOutputChannel()->sendMessage(QVariant::fromValue(edit)); | ||
| 276 | |||
| 277 | } else { | ||
| 278 | // apply immediately to local tree | ||
| 279 | edit.apply(_data, _sequencer.getWeakSharedObjectHash()); | ||
| 280 | |||
| 281 | // start sending it out | ||
| 282 | _sequencer.sendHighPriorityMessage(QVariant::fromValue(edit)); | ||
| 283 | } | ||
| 284 | } | ||
| 285 | |||
| 286 | void MetavoxelSystemClient::simulate(float deltaTime) { | ||
| 287 | Bitstream& out = _sequencer.startPacket(); | ||
| 288 | |||
| 289 | ClientStateMessage state = { getLOD() }; | ||
| 290 | out << QVariant::fromValue(state); | ||
| 291 | _sequencer.endPacket(); | ||
| 292 | |||
| 293 | // record the send | ||
| 294 | SendRecord record = { _sequencer.getOutgoingPacketNumber(), state.lod }; | ||
| 295 | _sendRecords.append(record); | ||
| 296 | } | 201 | } |
| 297 | 202 | ||
| 298 | int MetavoxelSystemClient::parseData(const QByteArray& packet) { | 203 | int MetavoxelSystemClient::parseData(const QByteArray& packet) { |
| @@ -302,48 +207,11 @@ int MetavoxelSystemClient::parseData(const QByteArray& packet) { · 3 unmodified lines | |||
| 302 | return packet.size(); | 207 | return packet.size(); |
| 303 | } | 208 | } |
| 304 | 209 | ||
| 305 | void MetavoxelSystemClient::sendData(const QByteArray& data) { | 210 | void MetavoxelSystemClient::sendDatagram(const QByteArray& data) { |
| 306 | NodeList::getInstance()->writeDatagram(data, _node); | 211 | NodeList::getInstance()->writeDatagram(data, _node); |
| 307 | Application::getInstance()->getBandwidthMeter()->outputStream(BandwidthMeter::METAVOXELS).updateValue(data.size()); | 212 | Application::getInstance()->getBandwidthMeter()->outputStream(BandwidthMeter::METAVOXELS).updateValue(data.size()); |
| 308 | } | 213 | } |
| 309 | 214 | ||
| 310 | void MetavoxelSystemClient::readPacket(Bitstream& in) { | ||
| 311 | QVariant message; | ||
| 312 | in >> message; | ||
| 313 | handleMessage(message, in); | ||
| 314 | |||
| 315 | // record the receipt | ||
| 316 | ReceiveRecord record = { _sequencer.getIncomingPacketNumber(), _data, _sendRecords.first().lod }; | ||
| 317 | _receiveRecords.append(record); | ||
| 318 | |||
| 319 | // reapply local edits | ||
| 320 | foreach (const DatagramSequencer::HighPriorityMessage& message, _sequencer.getHighPriorityMessages()) { | ||
| 321 | if (message.data.userType() == MetavoxelEditMessage::Type) { | ||
| 322 | message.data.value<MetavoxelEditMessage>().apply(_data, _sequencer.getWeakSharedObjectHash()); | ||
| 323 | } | ||
| 324 | } | ||
| 325 | } | ||
| 326 | |||
| 327 | void MetavoxelSystemClient::clearSendRecordsBefore(int index) { | ||
| 328 | _sendRecords.erase(_sendRecords.begin(), _sendRecords.begin() + index + 1); | ||
| 329 | } | ||
| 330 | |||
| 331 | void MetavoxelSystemClient::clearReceiveRecordsBefore(int index) { | ||
| 332 | _receiveRecords.erase(_receiveRecords.begin(), _receiveRecords.begin() + index + 1); | ||
| 333 | } | ||
| 334 | |||
| 335 | void MetavoxelSystemClient::handleMessage(const QVariant& message, Bitstream& in) { | ||
| 336 | int userType = message.userType(); | ||
| 337 | if (userType == MetavoxelDeltaMessage::Type) { | ||
| 338 | _data.readDelta(_receiveRecords.first().data, _receiveRecords.first().lod, in, _sendRecords.first().lod); | ||
| 339 | |||
| 340 | } else if (userType == QMetaType::QVariantList) { | ||
| 341 | foreach (const QVariant& element, message.toList()) { | ||
| 342 | handleMessage(element, in); | ||
| 343 | } | ||
| 344 | } | ||
| 345 | } | ||
| 346 | |||
| 347 | static void enableClipPlane(GLenum plane, float x, float y, float z, float w) { | 215 | static void enableClipPlane(GLenum plane, float x, float y, float z, float w) { |
| 348 | GLdouble coefficients[] = { x, y, z, w }; | 216 | GLdouble coefficients[] = { x, y, z, w }; |
| 349 | glClipPlane(plane, coefficients); | 217 | glClipPlane(plane, coefficients); |