void StandardLocationService::locationUpdate(UUID source, void* buffer, uint32 length) { Sirikata::Protocol::Loc::Container loc_container; bool parse_success = loc_container.ParseFromString( String((char*) buffer, length) ); if (!parse_success) { LOG_INVALID_MESSAGE_BUFFER(standardloc, error, ((char*)buffer), length); return; } if (loc_container.has_update_request()) { Sirikata::Protocol::Loc::LocationUpdateRequest request = loc_container.update_request(); TrackingType obj_type = type(source); if (obj_type == Local) { LocationMap::iterator loc_it = mLocations.find( source ); assert(loc_it != mLocations.end()); if (request.has_location()) { TimedMotionVector3f newloc( request.location().t(), MotionVector3f( request.location().position(), request.location().velocity() ) ); loc_it->second.location = newloc; notifyLocalLocationUpdated( source, loc_it->second.aggregate, newloc ); CONTEXT_SPACETRACE(serverLoc, mContext->id(), mContext->id(), source, newloc ); } if (request.has_bounds()) { BoundingSphere3f newbounds = request.bounds(); loc_it->second.bounds = newbounds; notifyLocalBoundsUpdated( source, loc_it->second.aggregate, newbounds ); } if (request.has_mesh()) { String newmesh = request.mesh(); loc_it->second.mesh = newmesh; notifyLocalMeshUpdated( source, loc_it->second.aggregate, newmesh ); } if (request.has_orientation()) { TimedMotionQuaternion neworient( request.orientation().t(), MotionQuaternion( request.orientation().position(), request.orientation().velocity() ) ); loc_it->second.orientation = neworient; notifyLocalOrientationUpdated( source, loc_it->second.aggregate, neworient ); } if (request.has_physics()) { String newphy = request.physics(); loc_it->second.physics = newphy; notifyLocalPhysicsUpdated( source, loc_it->second.aggregate, newphy ); } } else { // Warn about update to non-local object } } }
void BulletRigidBodyObject::updateObjectFromBullet(const btTransform& worldTrans) { assert(mFixed == false); LocationInfo& locinfo = mParent->info(mID); btVector3 pos = worldTrans.getOrigin(); btVector3 vel = mObjRigidBody->getLinearVelocity(); TimedMotionVector3f newLocation(mParent->context()->simTime(), MotionVector3f(Vector3f(pos.x(), pos.y(), pos.z()), Vector3f(vel.x(), vel.y(), vel.z()))); mParent->setLocation(mID, newLocation); BULLETLOG(insane, "Updating " << mID << " to velocity " << vel.x() << " " << vel.y() << " " << vel.z()); btQuaternion rot = worldTrans.getRotation(); btVector3 angvel = mObjRigidBody->getAngularVelocity(); Vector3f angvel_siri(angvel.x(), angvel.y(), angvel.z()); float angvel_angle = angvel_siri.normalizeThis(); TimedMotionQuaternion newOrientation( mParent->context()->simTime(), MotionQuaternion( Quaternion(rot.x(), rot.y(), rot.z(), rot.w()), Quaternion(angvel_siri, angvel_angle) ) ); mParent->setOrientation(mID, newOrientation); mParent->addUpdate(mID); }
void BulletCharacterObject::postTick(const Time& t) { LocationInfo& locinfo = mParent->info(mID); btTransform worldTrans = mGhostObject->getWorldTransform(); btVector3 pos = worldTrans.getOrigin(); TimedMotionVector3f newLocation(t, MotionVector3f(Vector3f(pos.x(), pos.y(), pos.z()), locinfo.props.location().velocity())); btQuaternion rot = worldTrans.getRotation(); TimedMotionQuaternion newOrientation( t, MotionQuaternion( Quaternion(rot.x(), rot.y(), rot.z(), rot.w()), locinfo.props.orientation().velocity() ) ); // Only update and report a change if it's big enough. This allows us to // stop sending updates if the object ends up essentially still. float32 pos_diff = (mParent->location(mID).position(t)-newLocation.position(t)).lengthSquared(); // This test is easy, but also conservative... float32 angle1, angle2; Vector3f axis1, axis2; mParent->orientation(mID).position(t).toAngleAxis(angle1, axis1); newOrientation.position(t).toAngleAxis(angle2, axis2); // FIXME what should this really be? This approach doesn't seem to really // work because we sometimes get 0 vectors and the constants seem odd... bool orient_changed = (axis1.dot(axis2) < 0.9) || (fabs(angle1-angle2) > 3.14159/180); if (pos_diff > 0.001 || orient_changed) { mParent->setLocation(mID, newLocation); mParent->setOrientation(mID, newOrientation); mParent->addUpdate(mID); } }
TimedMotionVector3f LocProtocolLocUpdate::location() const { Sirikata::Protocol::TimedMotionVector update_loc = mUpdate.location(); return TimedMotionVector3f( mSync.localTime(update_loc.t()), MotionVector3f(update_loc.position(), update_loc.velocity()) ); }
PresenceProperties() : mLoc(Time::null(), MotionVector3f(Vector3f::zero(), Vector3f::zero())), mOrientation(Time::null(), MotionQuaternion(Quaternion::identity(), Quaternion::identity())), mBounds(Vector3f::zero(), 0), mMesh(), mPhysics(), mIsAggregate(false), mParent(ObjectReference::null()) {}
void SimpleCameraObjectScript::moveAction(Vector3f dir, float amount) { // Get the updated position Time now = context()->simTime(); Location loc = mSelfProxy->extrapolateLocation(now); const Quaternion &orient = loc.getOrientation(); // Request updates from spcae TimedMotionVector3f newloc(now, MotionVector3f(Vector3f(loc.getPosition()), (orient * dir) * amount * WORLD_SCALE * .5) ); mParent->requestLocationUpdate(mID.space(), mID.object(), newloc); }
void PintoManagerLocationServiceCache::addAggregate(ServerID sid) { Lock lck(mMutex); assert(mServers.find(sid) == mServers.end()); SpaceServerData old_data = mServers[sid]; // Dummy info, we'll get updates soon. mServers[sid].location = TimedMotionVector3f(Time::null(), MotionVector3f()); mServers[sid].region = BoundingSphere3f(); mServers[sid].maxSize = 0; mServers[sid].aggregate = true; mServers[sid].tracking = 0; mServers[sid].removable = false; // Removal only by removeAggregate }
void CBRLocationServiceCache::addPlaceholderImposter( const ObjectID& uuid, const Vector3f& center_offset, const float32 center_bounds_radius, const float32 max_size, const String& zernike, const String& mesh ) { TimedMotionVector3f loc(mLoc->context()->simTime(), MotionVector3f(center_offset, Vector3f(0,0,0))); TimedMotionQuaternion orient; AggregateBoundingInfo bounds(Vector3f(0, 0, 0), center_bounds_radius, max_size); String phy; objectAdded( uuid.getAsUUID(), true, true, loc, orient, bounds, mesh, phy, zernike ); }
ProxyObject::ProxyObject(ProxyManager *man, const SpaceObjectReference&id, VWObjectPtr vwobj, const SpaceObjectReference& owner_sor) : SelfWeakPtr<ProxyObject>(), ProxyObjectProvider(), MeshProvider (), mID(id), mManager(man), mLoc(Time::null(), MotionVector3f(Vector3f::nil(), Vector3f::nil())), mOrientation(Time::null(), MotionQuaternion(Quaternion::identity(), Quaternion::identity())), mParent(vwobj), mMeshURI() { assert(mParent); mDefaultPort = mParent->bindODPPort(owner_sor); reset(); validate(); }
bool HostedObject::objectHostConnect(const SpaceID spaceID, const Location startingLocation, const BoundingSphere3f meshBounds, const String mesh, const String physics, const String query, const String zernike, const ObjectReference orefID, PresenceToken token) { ObjectReference oref = (orefID == ObjectReference::null()) ? ObjectReference(UUID::random()) : orefID; SpaceObjectReference connectingSporef (spaceID,oref); // Note: we always use Time::null() here. The server will fill in the // appropriate value. When we get the callback, we can fix this up. Time approx_server_time = Time::null(); if (mObjectHost->connect( getSharedPtr(), connectingSporef, spaceID, TimedMotionVector3f(approx_server_time, MotionVector3f( Vector3f(startingLocation.getPosition()), startingLocation.getVelocity()) ), TimedMotionQuaternion(approx_server_time,MotionQuaternion(startingLocation.getOrientation().normal(),Quaternion(startingLocation.getAxisOfRotation(),startingLocation.getAngularSpeed()))), //normalize orientations meshBounds, mesh, physics, query, zernike, std::tr1::bind(&HostedObject::handleConnected, getWeakPtr(), mObjectHost, _1, _2, _3), std::tr1::bind(&HostedObject::handleMigrated, getWeakPtr(), _1, _2, _3), std::tr1::bind(&HostedObject::handleStreamCreated, getWeakPtr(), _1, _2, token), std::tr1::bind(&HostedObject::handleDisconnected, getWeakPtr(), _1, _2) )) { mObjectHost->registerHostedObject(connectingSporef,getSharedPtr()); return true; }else { return false; } }
void StandardLocationService::receiveMessage(Message* msg) { assert(msg->dest_port() == SERVER_PORT_LOCATION); Sirikata::Protocol::Loc::BulkLocationUpdate contents; bool parsed = parsePBJMessage(&contents, msg->payload()); if (parsed) { for(int32 idx = 0; idx < contents.update_size(); idx++) { Sirikata::Protocol::Loc::LocationUpdate update = contents.update(idx); // Its possible we'll get an out of date update. We only use this update // if (a) we have this object marked as a replica object and (b) we don't // have this object marked as a local object if (type(update.object()) != Replica) continue; LocationMap::iterator loc_it = mLocations.find( update.object() ); // We can safely make this assertion right now because space server // to space server loc and prox are on the same reliable channel. If // this goes away then a) we can't make this assertion and b) we // need an OrphanLocUpdateManager to save updates where this // condition is false so they can be applied once the prox update // arrives. assert(loc_it != mLocations.end()); if (update.has_location()) { TimedMotionVector3f newloc( update.location().t(), MotionVector3f( update.location().position(), update.location().velocity() ) ); loc_it->second.location = newloc; notifyReplicaLocationUpdated( update.object(), newloc ); CONTEXT_SPACETRACE(serverLoc, msg->source_server(), mContext->id(), update.object(), newloc ); } if (update.has_orientation()) { TimedMotionQuaternion neworient( update.orientation().t(), MotionQuaternion( update.orientation().position(), update.orientation().velocity() ) ); loc_it->second.orientation = neworient; notifyReplicaOrientationUpdated( update.object(), neworient ); } if (update.has_bounds()) { BoundingSphere3f newbounds = update.bounds(); loc_it->second.bounds = newbounds; notifyReplicaBoundsUpdated( update.object(), newbounds ); } if (update.has_mesh()) { String newmesh = update.mesh(); loc_it->second.mesh = newmesh; notifyReplicaMeshUpdated( update.object(), newmesh ); } if (update.has_physics()) { String newphy = update.physics(); loc_it->second.physics = newphy; notifyReplicaPhysicsUpdated( update.object(), newphy ); } } } delete msg; }