diff --git a/OpenSim/Region/Framework/Scenes/SOPVehicle.cs b/OpenSim/Region/Framework/Scenes/SOPVehicle.cs index 2b33cf776c..897918ae07 100644 --- a/OpenSim/Region/Framework/Scenes/SOPVehicle.cs +++ b/OpenSim/Region/Framework/Scenes/SOPVehicle.cs @@ -406,6 +406,16 @@ namespace OpenSim.Region.Framework.Scenes ph.SetVehicle(vd); } + public bool CameraDecoupled + { + get + { + if((vd.m_flags & VehicleFlag.CAMERA_DECOUPLED) != 0) + return true; + return false; + } + } + private XmlTextWriter writer; private void XWint(string name, int i) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index fee3bcff88..0d6af77c97 100755 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -5431,7 +5431,6 @@ Label_GroupsDone: } } } - } public void DeleteFromStorage(UUID uuid) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index bf78c3f936..f7f18351e1 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2162,9 +2162,19 @@ namespace OpenSim.Region.Framework.Scenes { AddToPhysics(isPhysical, isPhantom, building, isPhysical); UpdatePhysicsSubscribedEvents(); // not sure if appliable here + if(!_VolumeDetectActive && + m_vehicleParams != null && + m_vehicleParams.CameraDecoupled && + m_localId == ParentGroup.RootPart.LocalId) + AddFlag(PrimFlags.CameraDecoupled); + else + RemFlag(PrimFlags.CameraDecoupled); } else + { PhysActor = null; // just to be sure + RemFlag(PrimFlags.CameraDecoupled); + } } } @@ -3539,6 +3549,7 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter set { m_vehicleParams = value; + } } @@ -3583,7 +3594,7 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter m_vehicleParams.ProcessVehicleFlags(param, remove); - if (_parentID ==0 && PhysActor != null) + if (_parentID == 0 && PhysActor != null) { PhysActor.VehicleFlags(param, remove); } @@ -4662,6 +4673,11 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter if (ParentGroup != null) { + if(UsePhysics && !SetPhantom && m_localId == ParentGroup.RootPart.LocalId && + m_vehicleParams != null && m_vehicleParams.CameraDecoupled) + AddFlag(PrimFlags.CameraDecoupled); + else + RemFlag(PrimFlags.CameraDecoupled); ParentGroup.HasGroupChanged = true; ScheduleFullUpdate(); } @@ -4722,9 +4738,16 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter if (VolumeDetectActive) // change if not the default only pa.SetVolumeDetect(1); - if (m_vehicleParams != null && LocalId == ParentGroup.RootPart.LocalId) + if (m_vehicleParams != null && m_localId == ParentGroup.RootPart.LocalId) + { m_vehicleParams.SetVehicle(pa); - + if(isPhysical && !isPhantom && m_vehicleParams.CameraDecoupled) + AddFlag(PrimFlags.CameraDecoupled); + else + RemFlag(PrimFlags.CameraDecoupled); + } + else + RemFlag(PrimFlags.CameraDecoupled); // we are going to tell rest of code about physics so better have this here PhysActor = pa; @@ -4800,6 +4823,7 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter ParentGroup.Scene.EventManager.TriggerObjectRemovedFromPhysicalScene(this); } + RemFlag(PrimFlags.CameraDecoupled); PhysActor = null; } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 643a479382..2dc6f486b7 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -5442,6 +5442,7 @@ namespace OpenSim.Region.Framework.Scenes Valid = true, MouseLook = this.m_mouseLook, CameraRotation = this.CameraRotation, + CameraAtAxis = this.CameraAtAxis }; } diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEDynamics.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEDynamics.cs index d8a2272cd3..456d9e9339 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODEDynamics.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODEDynamics.cs @@ -648,6 +648,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde break; } + // disable mouse steering + m_flags &= ~(VehicleFlag.MOUSELOOK_STEER | + VehicleFlag.MOUSELOOK_BANK | + VehicleFlag.CAMERA_DECOUPLED); m_lmDecay = (1.0f - 1.0f / m_linearMotorDecayTimescale); m_amDecay = 1.0f - 1.0f / m_angularMotorDecayTimescale; @@ -794,6 +798,16 @@ namespace OpenSim.Region.PhysicsModule.ubOde float ldampZ = 0; + bool mousemode = false; + if((m_flags & (VehicleFlag.MOUSELOOK_STEER |VehicleFlag.MOUSELOOK_BANK)) != 0 ) + mousemode = true; + + float bankingEfficiency; + if(mousemode) + bankingEfficiency = 0; + else + bankingEfficiency = m_bankingEfficiency; + // linear motor if (m_lmEfect > 0.01 && m_linearMotorTimescale < 1000) { @@ -967,7 +981,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde torque.Y += effpitch * ftmp; } - if (m_bankingEfficiency != 0 && Math.Abs(effroll) > 0.01) + if (bankingEfficiency != 0 && Math.Abs(effroll) > 0.01) { float broll = effroll; @@ -1018,57 +1032,107 @@ namespace OpenSim.Region.PhysicsModule.ubOde m_amdampZ = 1 / m_angularFrictionTimescale.Z; } - // angular motor - if (m_amEfect > 0.01 && m_angularMotorTimescale < 1000) + if(mousemode) { - tmpV = m_angularMotorDirection - curLocalAngVel; // velocity error - tmpV *= m_amEfect / m_angularMotorTimescale; // error to correct in this timestep - torque.X += tmpV.X * m_ampwr; - torque.Y += tmpV.Y * m_ampwr; - torque.Z += tmpV.Z; + CameraData cam = rootPrim.TryGetCameraData(); + if(cam.Valid && cam.MouseLook) + { + Vector3 dirv = cam.CameraAtAxis * irotq; - m_amEfect *= m_amDecay; - } - else - m_amEfect = 0; + float tmp; + if(Math.Abs(dirv.X) > 0.01f) + { + if (Math.Abs(dirv.Z) > 0.01) + { + tmp = -(float)Math.Atan2(dirv.Z, dirv.X) * m_angularMotorDirection.Y; + if(tmp < -4f) + tmp = -4f; + else if(tmp > 4f) + tmp = 4f; + torque.Y += (tmp - curLocalAngVel.Y) / m_angularMotorTimescale; + } - // angular deflection - if (m_angularDeflectionEfficiency > 0) - { - Vector3 dirv; - - if (curLocalVel.X > 0.01f) - dirv = curLocalVel; - else if (curLocalVel.X < -0.01f) - // use oposite - dirv = -curLocalVel; + if (Math.Abs(dirv.Y) > 0.01) + { + tmp = (float)Math.Atan2(dirv.Y, dirv.X) * m_angularMotorDirection.Z; + if(tmp < -4f) + tmp = -4f; + else if(tmp > 4f) + tmp = 4f; + torque.Z += (tmp - curLocalAngVel.Z) / m_angularMotorTimescale; + } + } + // angular friction + if (curLocalAngVel.X != 0 || curLocalAngVel.Y != 0 || curLocalAngVel.Z != 0) + { + torque.X -= curLocalAngVel.X * m_amdampX; + torque.Y -= curLocalAngVel.Y * m_amdampY; + torque.Z -= curLocalAngVel.Z * m_amdampZ; + } + } else { - // make it fall into small positive x case - dirv.X = 0.01f; - dirv.Y = curLocalVel.Y; - dirv.Z = curLocalVel.Z; - } - - float ftmp = m_angularDeflectionEfficiency / m_angularDeflectionTimescale; - - if (Math.Abs(dirv.Z) > 0.01) - { - torque.Y += - (float)Math.Atan2(dirv.Z, dirv.X) * ftmp; - } - - if (Math.Abs(dirv.Y) > 0.01) - { - torque.Z += (float)Math.Atan2(dirv.Y, dirv.X) * ftmp; + if (curLocalAngVel.X != 0 || curLocalAngVel.Y != 0 || curLocalAngVel.Z != 0) + { + torque.X -= curLocalAngVel.X * 10f; + torque.Y -= curLocalAngVel.Y * 10f; + torque.Z -= curLocalAngVel.Z * 10f; + } } } - - // angular friction - if (curLocalAngVel.X != 0 || curLocalAngVel.Y != 0 || curLocalAngVel.Z != 0) + else { - torque.X -= curLocalAngVel.X * m_amdampX; - torque.Y -= curLocalAngVel.Y * m_amdampY; - torque.Z -= curLocalAngVel.Z * m_amdampZ; + // angular motor + if (m_amEfect > 0.01 && m_angularMotorTimescale < 1000) + { + tmpV = m_angularMotorDirection - curLocalAngVel; // velocity error + tmpV *= m_amEfect / m_angularMotorTimescale; // error to correct in this timestep + torque.X += tmpV.X * m_ampwr; + torque.Y += tmpV.Y * m_ampwr; + torque.Z += tmpV.Z; + + m_amEfect *= m_amDecay; + } + else + m_amEfect = 0; + + // angular deflection + if (m_angularDeflectionEfficiency > 0) + { + Vector3 dirv; + + if (curLocalVel.X > 0.01f) + dirv = curLocalVel; + else if (curLocalVel.X < -0.01f) + // use oposite + dirv = -curLocalVel; + else + { + // make it fall into small positive x case + dirv.X = 0.01f; + dirv.Y = curLocalVel.Y; + dirv.Z = curLocalVel.Z; + } + + float ftmp = m_angularDeflectionEfficiency / m_angularDeflectionTimescale; + + if (Math.Abs(dirv.Z) > 0.01) + { + torque.Y += - (float)Math.Atan2(dirv.Z, dirv.X) * ftmp; + } + + if (Math.Abs(dirv.Y) > 0.01) + { + torque.Z += (float)Math.Atan2(dirv.Y, dirv.X) * ftmp; + } + } + + if (curLocalAngVel.X != 0 || curLocalAngVel.Y != 0 || curLocalAngVel.Z != 0) + { + torque.X -= curLocalAngVel.X * m_amdampX; + torque.Y -= curLocalAngVel.Y * m_amdampY; + torque.Z -= curLocalAngVel.Z * m_amdampZ; + } } force *= dmass.mass;