void VRGeometry::loadContent(xmlpp::Element* e) { VRTransform::loadContent(e); source.type = toInt(e->get_attribute("sourcetype")->get_value().c_str()); source.parameter = e->get_attribute("sourceparam")->get_value(); string p1, p2; stringstream ss; VRGeometry* g; // get source info // construct data from that switch(source.type) { case CODE: return; case SCRIPT: break; case FILE: ss << source.parameter; ss >> p1; ss >> p2; g = VRImport::get()->loadGeometry(p1, p2); if (g) setMesh( g->getMesh(), source, true ); else cout << "failed to load " << p2 << " from file " << p1 << endl; break; case PRIMITIVE: ss << source.parameter; ss >> p1; getline(ss, p2); setPrimitive(p1, p2); break; } }
bool CSGGeometry::disableEditMode() { if (children.size() != 2) { cout << "CSGGeometry: Warning: editMode disabled with less than 2 children. Doing nothing.\n"; return false; } vector<CGAL::Polyhedron*> polys(2,0); // We need two child geometries to work with for (int i=0; i<2; i++) { // Prepare the polyhedra VRObject *obj = children[i]; obj->setVisible(false); if (obj->getType() == string("Geometry")) { VRGeometry *geo = dynamic_cast<VRGeometry*>(obj); cout << "child: " << geo->getName() << " toPolyhedron\n"; bool success; try { polys[i] = toPolyhedron( geo->getMesh(), geo->getWorldMatrix(), success ); } catch (exception e) { success = false; cout << getName() << ": toPolyhedron exception: " << e.what() << endl; } if (!success) { cout << getName() << ": toPolyhedron went totaly wrong :(\n"; //setCSGGeometry(polys[i]); //obj->setVisible(true); // We stay in edit mode, so both children need to be visible return false; } continue; } if(obj->getType() == "CSGGeometry") { CSGGeometry *geo = dynamic_cast<CSGGeometry*>(obj); polys[i] = geo->getCSGGeometry(); // TODO: where does this come from?? keep the old! continue; } cout << "Warning! polyhedron " << i << " not acquired because "; cout << obj->getName() << " has wrong type " << obj->getType(); cout << ", it should be 'Geometry' or 'CSGGeometry'!" << endl; } if (polys[0] == 0) cout << "Warning! first polyhedron is 0! " << children[0]->getName() << endl; if (polys[1] == 0) cout << "Warning! second polyhedron is 0! " << children[1]->getName() << endl; if (polys[0] == 0 || polys[1] == 0) return false; if (polyhedron) delete polyhedron; polyhedron = 0; if (operation == "unite") polyhedron = unite(polys[0], polys[1]); else if(operation == "subtract") polyhedron = subtract(polys[0], polys[1]); else if(operation == "intersect") polyhedron = intersect(polys[0], polys[1]); else cout << "CSGGeometry: Warning: unexpected CSG operation!\n"; // Clean up for (auto p : polys) delete p; if (polyhedron == 0) return false; setCSGGeometry(polyhedron); return true; }
void VRStroke::strokeStrew(VRGeometry* geo) { if (geo == 0) return; mode = 1; strewGeo = geo; clearChildren(); for (uint i=0; i<paths.size(); i++) { vector<Vec3f> pnts = paths[i]->getPositions(); for (uint j=0; j<pnts.size(); j++) { Vec3f p = pnts[j]; VRGeometry* g = (VRGeometry*)geo->duplicate(); addChild(g); g->translate(p); } } }
TrafficSimulation::TrafficSimulation(MapCoordinator *mapCoordinator, const string& host) : driverVehicleRadius(5.0), loadedMaps(), collisionHandler(NULL), client(host), mapCoordinator(mapCoordinator), viewDistance(200), player(NULL), playerCreated(false), communicationThreadId(-1), networkDataMutex(), receivedData(), dataToSend(), meshes(), vehicles(), lightBulbs(), noConnection(false), communicationThreadMutex() { // Add a dummy model for unknown vehicle types VRGeometry* geo = new VRGeometry("vehicle_type_unknown"); geo->addAttachment("dynamicaly_generated", 0); geo->setPrimitive("Box", "1 1 2 1 1 1"); meshes[404] = geo; a_red = new VRMaterial("a_red"); a_orange = new VRMaterial("a_orange"); a_green = new VRMaterial("a_green"); a_red->setDiffuse(Vec3f(1,0,0)); a_orange->setDiffuse(Vec3f(1,0.8,0.1)); a_green->setDiffuse(Vec3f(0,1,0.1)); a_red->setLit(false); a_orange->setLit(false); a_green->setLit(false); //VRFunction<int>* fkt = new VRFunction<int>( "traffic update fkt", boost::bind(&TrafficSimulation::updateScene, this) ); //VRSceneManager::get()->getActiveScene()->addUpdateFkt(fkt); }
VRObject* VRGeometry::copy(vector<VRObject*> children) { VRGeometry* geo = new VRGeometry(getBaseName()); geo->setMesh(mesh); geo->setMaterial(mat); geo->source = source; geo->setVisible(isVisible()); geo->setPickable(isPickable()); geo->setMatrix(getMatrix()); return geo; }
void VRGeometry::showGeometricData(string type, bool b) { if (dataLayer.count(type)) dataLayer[type]->destroy(); VRGeometry* geo = new VRGeometry("DATALAYER_"+getName()+"_"+type, true); dataLayer[type] = geo; addChild(geo); GeoColor3fPropertyRecPtr cols = GeoColor3fProperty::create(); GeoPnt3fPropertyRecPtr pos = GeoPnt3fProperty::create(); GeoUInt32PropertyRecPtr inds = GeoUInt32Property::create(); Pnt3f p; Vec3f n; if (type == "Normals") { GeoVectorPropertyRecPtr g_norms = mesh->getNormals(); GeoVectorPropertyRecPtr g_pos = mesh->getPositions(); for (uint i=0; i<g_norms->size(); i++) { p = g_pos->getValue<Pnt3f>(i); n = g_norms->getValue<Vec3f>(i); pos->addValue(p); pos->addValue(p+n*0.1); cols->addValue(Vec3f(1,1,1)); cols->addValue(Vec3f(abs(n[0]),abs(n[1]),abs(n[2]))); inds->addValue(2*i); inds->addValue(2*i+1); } geo->setPositions(pos); geo->setType(GL_LINE); geo->setColors(cols); geo->setIndices(inds); } VRMaterial* m = new VRMaterial("some-mat"); geo->setMaterial(m); m->setLit(false); }
void TrafficSimulation::update() { networkDataMutex.lock(); // Update the position of the player to be send to the server if (player != NULL) { // Move the vehicle Value vehicle; vehicle["id"] = 0; Value pos; Vec3f worldPosition = player->getFrom(); pos[0u] = worldPosition[0]; pos[1] = worldPosition[1]; pos[2] = worldPosition[2]; vehicle["pos"] = pos; // Pack as the requested array entry dataToSend["moveVehicles"][0] = vehicle; } if (!receivedData.isNull()) { //cout << "Received data\n"; // New data received per network. Update the positions of vehicles and the states of traffic lights // A set which contains the IDs of the currently existing vehicles. // If data for one of those is received, the entry in the set will be removed. // All vehicles that are in the set after the loop finished are no longer in the // area and can be deleted. set<uint> vehicleIDs; for (auto iter : vehicles) vehicleIDs.insert(iter.first); if (!receivedData["vehicles"].isNull() && receivedData["vehicles"].isArray()) { // Update the vehicles //cout << "Received vehicles " << receivedData["vehicles"].size(); // A set for possible collisions // Add them all to the set and resolve them later on to avoid doubled checks set< pair<unsigned int, unsigned int> > collisions; // Sleeps for 10ms each tick, but the send deltas are for one second // Use only a part of them to avoid moving too fast static const float partDelta = 10 / 1000; for (auto vehicleIter : receivedData["vehicles"]) { // Check if the values have valid types if (!vehicleIter["id"].isConvertibleTo(uintValue) || !vehicleIter["pos"].isConvertibleTo(arrayValue) || !vehicleIter["pos"][0].isConvertibleTo(realValue) || !vehicleIter["pos"][1].isConvertibleTo(realValue) || !vehicleIter["pos"][2].isConvertibleTo(realValue) || !vehicleIter["dPos"].isConvertibleTo(arrayValue) || !vehicleIter["dPos"][0].isConvertibleTo(realValue) || !vehicleIter["dPos"][1].isConvertibleTo(realValue) || !vehicleIter["dPos"][2].isConvertibleTo(realValue) || !vehicleIter["angle"].isConvertibleTo(arrayValue) || !vehicleIter["angle"][0].isConvertibleTo(realValue) || !vehicleIter["angle"][1].isConvertibleTo(realValue) || !vehicleIter["angle"][2].isConvertibleTo(realValue) || !vehicleIter["dAngle"].isConvertibleTo(arrayValue) || !vehicleIter["dAngle"][0].isConvertibleTo(realValue) || !vehicleIter["dAngle"][1].isConvertibleTo(realValue) || !vehicleIter["dAngle"][2].isConvertibleTo(realValue)) { cout << "TrafficSimulation: Warning: Received invalid vehicle data.\n"; continue; } uint ID = vehicleIter["id"].asUInt(); if (vehicles.count(ID) == 0) { // The vehicle is new, create it if (!vehicleIter["vehicle"].isConvertibleTo(uintValue) || !vehicleIter["driver"].isConvertibleTo(uintValue)) { cout << "TrafficSimulation: Warning: Received invalid vehicle data.\n"; continue; } uint vID = vehicleIter["vehicle"].asUInt(); if (meshes.count(vID) == 0) { // If it is bigger than 500 it is our user-controlled vehicle if (vID < 500) cout << "TrafficSimulation: Warning: Received unknown vehicle type " << vID << ".\n"; continue; } Vehicle v; v.id = ID; v.vehicleTypeId = vID; v.driverTypeId = vehicleIter["driver"].asUInt(); if (meshes.count(v.vehicleTypeId) == 0) v.vehicleTypeId = 404; v.geometry = (VRGeometry*)meshes[v.vehicleTypeId]->duplicate(true); v.geometry->addAttachment("dynamicaly_generated", 0); // Add it to the map vehicles.insert(make_pair(v.id, v)); } else vehicleIDs.erase(ID); // Already (and still) exists, remove its ID from the vehicle-id-set // Now the vehicle exists, update its position and state Vehicle& v = vehicles[ID]; v.pos = Vec3f(vehicleIter["pos"][0].asFloat(), vehicleIter["pos"][1].asFloat(), vehicleIter["pos"][2].asFloat()); v.deltaPos = Vec3f(vehicleIter["dPos"][0].asFloat(), vehicleIter["dPos"][1].asFloat(), vehicleIter["dPos"][2].asFloat()); v.deltaPos *= partDelta; v.orientation = Vec3f(vehicleIter["angle"][0].asFloat(), vehicleIter["angle"][1].asFloat(), vehicleIter["angle"][2].asFloat()); v.deltaOrientation = Vec3f(vehicleIter["dAngle"][0].asFloat(), vehicleIter["dAngle"][1].asFloat(), vehicleIter["dAngle"][2].asFloat()); v.deltaOrientation *= partDelta; if (!vehicleIter["state"].isNull() && vehicleIter["state"].isArray()) { v.state = Vehicle::NONE; for (auto state : vehicleIter["state"]) { if (!state.isConvertibleTo(stringValue)) continue; if(state.asString() == "rightIndicator") { v.state |= Vehicle::RIGHT_INDICATOR; } else if(state.asString() == "leftIndicator") { v.state |= Vehicle::LEFT_INDICATOR; } else if(state.asString() == "accelerating") { v.state |= Vehicle::ACCELERATING; } else if(state.asString() == "braking") { v.state |= Vehicle::BRAKING; } else if(state.asString() == "waiting") { v.state |= Vehicle::WAITING; } else if(state.asString() == "blocked") { v.state |= Vehicle::BLOCKED; } else if(state.asString() == "collision") { v.state |= Vehicle::COLLIDED; } } } if (!vehicleIter["colliding"].isNull() && vehicleIter["colliding"].isArray()) { for (auto collisionIter : vehicleIter["colliding"]) { if (!collisionIter.isConvertibleTo(uintValue)) continue; uint other = collisionIter.asUInt(); if (other < v.id) collisions.insert(make_pair(other, v.id)); else collisions.insert(make_pair(v.id, other)); } } } // End vehicle iteration // Okay, all vehicles are updated now // Resolve collisions if (collisionHandler != NULL) { for (auto c : collisions) { if (collisionHandler(vehicles[c.first], vehicles[c.second])) { dataToSend["collision"].append(c.first); dataToSend["collision"].append(c.second); } } } } // End vehicle updates // Remove vehicles which are no longer on the map for (auto v : vehicleIDs) { vehicles[v].geometry->destroy(); vehicles.erase(v); } // Get traffic light updates if (!receivedData["trafficlights"].isNull() && receivedData["trafficlights"].isArray()) { // The light bulbs in the array will be moved around arbitrary whichever light posts are given // If there are not enough bulbs in the array, more are added // If there are too many bulbs, they are deleted size_t bulbIndex = 0; static const double postHeight = 2; static const double bulbSize = 1; // Note: If you change this value from 2, change the value further down in new VRGeometry(), too. for (auto lightpost : receivedData["trafficlights"]) { if (!lightpost.isObject()) continue; if (!lightpost["at"].isConvertibleTo(uintValue) || !lightpost["to"].isConvertibleTo(uintValue) || lightpost["state"].isNull() || !lightpost["state"].isArray()) { cout << "TrafficSimulation: Warning: Received invalid light post data.\n"; continue; } // Calculate the vector of the street // Get the node positions Vec2f atPos, toPos; string atId = lexical_cast<string>(lightpost["at"].asUInt()); string toId = lexical_cast<string>(lightpost["to"].asUInt()); bool foundAt = false, foundTo = false; for (auto mapIter : loadedMaps) { for (auto nodeIter : mapIter->osmNodes) { if (!foundAt && nodeIter->id == atId) { atPos = mapCoordinator->realToWorld(Vec2f(nodeIter->lat, nodeIter->lon)); foundAt = true; } if (!foundTo && nodeIter->id == toId) { toPos = mapCoordinator->realToWorld(Vec2f(nodeIter->lat, nodeIter->lon)); foundTo = true; } if (foundAt && foundTo) break; } if (foundAt && foundTo) break; } Vec2f streetOffset = toPos - atPos; const float prevLength = streetOffset.length(); streetOffset.normalize(); streetOffset *= min(prevLength / 2, Config::get()->STREET_WIDTH); Vec2f normal(-streetOffset[1], streetOffset[0]); normal.normalize(); normal *= Config::get()->STREET_WIDTH; streetOffset += atPos; // streetOffset now contains a position in the center of a street a bit away from the crossing // normal is a vector that is orthogonal to the street // Now iterate over the lanes and hang up the lights double lane = -0.5; for (auto light : lightpost["state"]) { lane += 1; if (!light.isConvertibleTo(stringValue)) continue; while (bulbIndex+1 >= lightBulbs.size()) { if (VRSceneManager::get()->getActiveScene() == NULL) break; // Create a new light VRGeometry* geo = new VRGeometry("ampel"); geo->addAttachment("dynamicaly_generated", 0); geo->setPrimitive("Sphere", "0.5 2"); // The first value has to be half of bulbSize geo->setMaterial(a_red); VRSceneManager::get()->getActiveScene()->add(geo); lightBulbs.push_back(geo); } // color switch VRGeometry* bulb = lightBulbs[bulbIndex++]; Vec3f p = Vec3f(streetOffset[0] + lane * normal[0], postHeight, streetOffset[1] + lane * normal[1]); string lcol = light.asString(); if (lcol == "red") { bulb->setWorldPosition(p+Vec3f(0,3 * bulbSize,0)); bulb->setMaterial(a_red); } else if (lcol == "redamber") { bulb->setWorldPosition(p+Vec3f(0,3 * bulbSize,0)); bulb->setMaterial(a_red); bulb = lightBulbs[bulbIndex++]; bulb->setWorldPosition(p+Vec3f(0,2 * bulbSize,0)); bulb->setMaterial(a_orange); } else if (lcol == "amber") { bulb->setWorldPosition(p+Vec3f(0,2 * bulbSize,0)); bulb->setMaterial(a_orange); } else if (lcol == "green") { bulb->setWorldPosition(p+Vec3f(0,bulbSize,0)); bulb->setMaterial(a_green); } } } // Remove unused lightbulbs while (bulbIndex < lightBulbs.size()) { lightBulbs.back()->destroy(); lightBulbs.pop_back(); } } } networkDataMutex.unlock(); // Advance the vehicles a bit //cout << "Update " << vehicles.size() << " vehicles\n"; for (auto v : vehicles) { Vec3f p = v.second.pos; p[1] = -1.2;//TODO: get right street height v.second.geometry->setFrom(p); v.second.geometry->setDir(v.second.pos - v.second.orientation); v.second.pos += v.second.deltaPos; v.second.orientation += v.second.deltaOrientation; } }
void VRStroke::strokeProfile(vector<Vec3f> profile, bool closed, bool lit) { mode = 0; this->profile = profile; this->closed = closed; this->lit = lit; GeoUInt8PropertyRecPtr Type = GeoUInt8Property::create(); GeoUInt32PropertyRefPtr Length = GeoUInt32Property::create(); GeoPnt3fPropertyRecPtr Pos = GeoPnt3fProperty::create(); GeoVec3fPropertyRefPtr Norms = GeoVec3fProperty::create(); GeoVec3fPropertyRefPtr Colors = GeoVec3fProperty::create(); GeoUInt32PropertyRefPtr Indices = GeoUInt32Property::create(); Vec3f z = Vec3f(0,0,1); if (profile.size() == 1) Type->addValue(GL_LINES); else Type->addValue(GL_QUADS); clearChildren(); for (uint i=0; i<paths.size(); i++) { vector<Vec3f> pnts = paths[i]->get(); vector<Vec3f> norms = paths[i]->getNormals(); vector<Vec3f> cols = paths[i]->getColors(); Vec3f _p; for (uint j=0; j<pnts.size(); j++) { Vec3f p = pnts[j]; Vec3f n = norms[j]; Vec3f c = cols[j]; //float ca = n.dot(z); Matrix m; //MatrixLookAt(m, Vec3f(0,0,0), n, z.cross(n)); MatrixLookAt(m, Vec3f(0,0,0), n, Vec3f(0,1,0)); // add new profile points and normals for (uint k=0; k<profile.size(); k++) { Vec3f tmp = profile[k]; m.mult(tmp, tmp); Pos->addValue(p+tmp); tmp.normalize(); Norms->addValue(tmp); Colors->addValue(c); } if (j==0 and profile.size() > 1) continue; // add line if (profile.size() == 1) { int N = Pos->size(); Indices->addValue(N-2); Indices->addValue(N-1); } else { // add quad for (uint k=0; k<profile.size()-1; k++) { int N1 = Pos->size() - 2*profile.size() + k; int N2 = Pos->size() - profile.size() + k; Indices->addValue(N1); Indices->addValue(N2); Indices->addValue(N2+1); Indices->addValue(N1+1); //cout << "\nN1N2 " << N1 << " " << N2 << " " << N2+1 << " " << N1+1 << flush; } if (closed) { int N0 = Pos->size() - 2*profile.size(); int N1 = Pos->size() - profile.size() - 1; int N2 = Pos->size() - 1; Indices->addValue(N1); Indices->addValue(N2); Indices->addValue(N1+1); Indices->addValue(N0); //cout << "\nN1N2 " << N1 << " " << N2 << " " << N1+1 << " " << N0 << flush; } } } } Length->addValue(Indices->size()); SimpleMaterialRecPtr Mat = SimpleMaterial::create(); GeometryRecPtr g = Geometry::create(); g->setTypes(Type); g->setLengths(Length); g->setPositions(Pos); g->setNormals(Norms); g->setColors(Colors); g->setIndices(Indices); g->setMaterial(Mat); Mat->setLit(lit); VRGeometry* geo = new VRGeometry("stroke"); geo->setMesh(g); addChild(geo); }