From 76569ff4fba09f22ed4a06b8073deaed7f64a2e3 Mon Sep 17 00:00:00 2001 From: MW Date: Sat, 10 Mar 2007 20:30:25 +0000 Subject: A PhysX physics plugin (that actually uses physX now but currently only works on windows) Can now change direction when walking without stopping Flying works when using the Physx dll --- src/world/Avatar.cs | 103 ++++++++++++++++++++++++++++++++++++++++++------- src/world/Primitive.cs | 83 ++++++++++++++++++++++++++++++++++----- src/world/World.cs | 9 +++-- 3 files changed, 169 insertions(+), 26 deletions(-) (limited to 'src/world') diff --git a/src/world/Avatar.cs b/src/world/Avatar.cs index c09c008..facfeee 100644 --- a/src/world/Avatar.cs +++ b/src/world/Avatar.cs @@ -11,15 +11,17 @@ namespace OpenSim.world { public class Avatar : Entity { + public static bool PhysicsEngineFlying; public string firstname; public string lastname; public OpenSimClient ControllingClient; private PhysicsActor _physActor; private static libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock AvatarTemplate; private bool updateflag; - private bool walking; + private byte movementflag; private List forcesList = new List(); private short _updateCount; + private Axiom.MathLib.Quaternion bodyRot; public Avatar(OpenSimClient TheClient) { ServerConsole.MainConsole.Instance.WriteLine("Avatar.cs - Loading details from grid (DUMMY)"); @@ -77,14 +79,14 @@ namespace OpenSim.world } updateflag =false; - this._updateCount = 0; + //this._updateCount = 0; } else { - if(walking) - { + //if((movementflag & 1) !=0) + //{ _updateCount++; - if(_updateCount>3) + if(( (!PhysicsEngineFlying) && (_updateCount>3)) || (_updateCount>0)) { //It has been a while since last update was sent so lets send one. ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = CreateTerseBlock(); @@ -98,7 +100,7 @@ namespace OpenSim.world } _updateCount = 0; } - } + //} } } @@ -249,36 +251,111 @@ namespace OpenSim.world } public void HandleUpdate(AgentUpdatePacket pack) { - if(((uint)pack.AgentData.ControlFlags & (uint)MainAvatar.AgentUpdateFlags.AGENT_CONTROL_AT_POS) !=0) { - if(!walking) + if(((uint)pack.AgentData.ControlFlags & (uint)MainAvatar.AgentUpdateFlags.AGENT_CONTROL_FLY) !=0) + { + this._physActor.Flying = true; + } + else + { + this._physActor.Flying = false; + } + if(((uint)pack.AgentData.ControlFlags & (uint)MainAvatar.AgentUpdateFlags.AGENT_CONTROL_AT_POS) !=0) { + Axiom.MathLib.Quaternion q = new Axiom.MathLib.Quaternion(pack.AgentData.BodyRotation.W, pack.AgentData.BodyRotation.X, pack.AgentData.BodyRotation.Y, pack.AgentData.BodyRotation.Z); + if(((movementflag & 1) ==0) || (q!= this.bodyRot)) { - //we should add a new force to the list + //we should add a new force to the list // but for now we will deal with velocities NewForce newVelocity = new NewForce(); Axiom.MathLib.Vector3 v3 = new Axiom.MathLib.Vector3(1, 0, 0); - Axiom.MathLib.Quaternion q = new Axiom.MathLib.Quaternion(pack.AgentData.BodyRotation.W, pack.AgentData.BodyRotation.X, pack.AgentData.BodyRotation.Y, pack.AgentData.BodyRotation.Z); Axiom.MathLib.Vector3 direc = q * v3; direc.Normalize(); //work out velocity for sim physics system direc = direc * ((0.03f) * 128f); + if(this._physActor.Flying) + direc *=2; + + newVelocity.X = direc.x; + newVelocity.Y = direc.y; + newVelocity.Z = direc.z; + this.forcesList.Add(newVelocity); + movementflag = 1; + this.bodyRot = q; + } + } + else if((((uint)pack.AgentData.ControlFlags & (uint)MainAvatar.AgentUpdateFlags.AGENT_CONTROL_UP_POS) !=0) &&(PhysicsEngineFlying)) { + if(((movementflag & 2) ==0) && this._physActor.Flying) + { + //we should add a new force to the list + // but for now we will deal with velocities + NewForce newVelocity = new NewForce(); + Axiom.MathLib.Vector3 v3 = new Axiom.MathLib.Vector3(0, 0, 1); + Axiom.MathLib.Vector3 direc = v3; + direc.Normalize(); + + //work out velocity for sim physics system + direc = direc * ((0.03f) * 128f *2); + newVelocity.X = direc.x; + newVelocity.Y = direc.y; + newVelocity.Z = direc.z; + this.forcesList.Add(newVelocity); + movementflag = 2; + } + } + else if((((uint)pack.AgentData.ControlFlags & (uint)MainAvatar.AgentUpdateFlags.AGENT_CONTROL_UP_NEG) !=0) && (PhysicsEngineFlying)) { + if(((movementflag & 4) ==0) && this._physActor.Flying) + { + //we should add a new force to the list + // but for now we will deal with velocities + NewForce newVelocity = new NewForce(); + Axiom.MathLib.Vector3 v3 = new Axiom.MathLib.Vector3(0, 0, -1); + //Axiom.MathLib.Quaternion q = new Axiom.MathLib.Quaternion(pack.AgentData.BodyRotation.W, pack.AgentData.BodyRotation.X, pack.AgentData.BodyRotation.Y, pack.AgentData.BodyRotation.Z); + Axiom.MathLib.Vector3 direc = v3; + direc.Normalize(); + + //work out velocity for sim physics system + direc = direc * ((0.03f) * 128f *2); + newVelocity.X = direc.x; + newVelocity.Y = direc.y; + newVelocity.Z = direc.z; + this.forcesList.Add(newVelocity); + movementflag = 4; + } + } + else if(((uint)pack.AgentData.ControlFlags & (uint)MainAvatar.AgentUpdateFlags.AGENT_CONTROL_AT_NEG) !=0) { + Axiom.MathLib.Quaternion q = new Axiom.MathLib.Quaternion(pack.AgentData.BodyRotation.W, pack.AgentData.BodyRotation.X, pack.AgentData.BodyRotation.Y, pack.AgentData.BodyRotation.Z); + if(((movementflag & 8) ==0) || (q!= this.bodyRot)) + { + //we should add a new force to the list + // but for now we will deal with velocities + NewForce newVelocity = new NewForce(); + Axiom.MathLib.Vector3 v3 = new Axiom.MathLib.Vector3(-1, 0, 0); + Axiom.MathLib.Vector3 direc = q * v3; + direc.Normalize(); + + //work out velocity for sim physics system + direc = direc * ((0.03f) * 128f); + if(this._physActor.Flying) + direc *=2; + newVelocity.X = direc.x; newVelocity.Y = direc.y; newVelocity.Z = direc.z; this.forcesList.Add(newVelocity); - walking=true; + movementflag = 8; + this.bodyRot = q; } } else { - if(walking) + if((movementflag) !=0) { NewForce newVelocity = new NewForce(); newVelocity.X = 0; newVelocity.Y = 0; newVelocity.Z = 0; this.forcesList.Add(newVelocity); - walking = false; + movementflag = 0; } } } diff --git a/src/world/Primitive.cs b/src/world/Primitive.cs index 0d7d951..6be33ef 100644 --- a/src/world/Primitive.cs +++ b/src/world/Primitive.cs @@ -5,6 +5,7 @@ using OpenSim.types; using libsecondlife; using libsecondlife.Packets; using GridInterfaces; +using PhysicsSystem; namespace OpenSim.world { @@ -16,8 +17,21 @@ namespace OpenSim.world protected bool newPrimFlag; protected bool updateFlag; protected bool dirtyFlag; - protected ObjectUpdatePacket OurPacket; + private ObjectUpdatePacket OurPacket; + private PhysicsActor _physActor; + private bool physicsEnabled; + public bool PhysicsEnabled + { + get + { + return physicsEnabled; + } + set + { + physicsEnabled = value; + } + } public bool UpdateFlag { get @@ -41,6 +55,14 @@ namespace OpenSim.world return this.primData.Scale; } } + public PhysicsActor PhysActor + { + set + { + this._physActor = value; + } + } + public Primitive() { mesh_cutbegin = 0.0f; @@ -61,6 +83,16 @@ namespace OpenSim.world return mesh; } + public void UpdatePosition( LLVector3 pos) + { + this.position = pos; + if(this._physActor != null && this.physicsEnabled) + { + this._physActor.Position = new PhysicsVector(pos.X, pos.Y, pos.Z); + } + this.updateFlag = true; + } + public override void update() { if(this.newPrimFlag) @@ -89,13 +121,39 @@ namespace OpenSim.world } this.dirtyFlag = false; } - + else + { + if(this._physActor != null && this.physicsEnabled) + { + ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket(); + terse.RegionData.RegionHandle = OpenSim_Main.cfg.RegionHandle; // FIXME + terse.RegionData.TimeDilation = 64096; + terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1]; + terse.ObjectData[0] = this.CreateImprovedBlock(); + foreach(OpenSimClient client in OpenSim_Main.sim.ClientThreads.Values) { + client.OutPacket(terse); + } + } + } } public void UpdateClient(OpenSimClient RemoteClient) { - byte[] pb = this.position.GetBytes(); + + LLVector3 lPos; + if( this._physActor != null && this.physicsEnabled) + { + PhysicsVector pPos = this._physActor.Position; + lPos = new LLVector3( pPos.X, pPos.Y, pPos.Z); + } + else + { + lPos = this.position; + } + byte[] pb = lPos.GetBytes(); Array.Copy(pb, 0, OurPacket.ObjectData[0].ObjectData, 0, pb.Length); + + // OurPacket should be update with the follwing in updateShape() rather than having to do it here OurPacket.ObjectData[0].OwnerID = this.primData.OwnerID; OurPacket.ObjectData[0].PCode = this.primData.PCode; OurPacket.ObjectData[0].PathBegin = this.primData.PathBegin; @@ -137,7 +195,6 @@ namespace OpenSim.world this.primData.PathCurve = addPacket.PathCurve; this.primData.ProfileCurve = addPacket.ProfileCurve; this.primData.ProfileHollow = addPacket.ProfileHollow; - this.primData.PathRadiusOffset = addPacket.PathRadiusOffset; this.primData.PathRevolutions = addPacket.PathRevolutions; this.primData.PathTaperX = addPacket.PathTaperX; @@ -145,7 +202,6 @@ namespace OpenSim.world this.primData.PathTwist = addPacket.PathTwist; this.primData.PathTwistBegin =addPacket.PathTwistBegin; this.dirtyFlag = true; - } public void CreateFromPacket( ObjectAddPacket addPacket, LLUUID agentID, uint localID) @@ -162,7 +218,6 @@ namespace OpenSim.world objupdate.ObjectData[0].ExtraParams = new byte[1]; objupdate.ObjectData[0].MediaURL = new byte[0]; objupdate.ObjectData[0].NameValue = new byte[0]; - objupdate.ObjectData[0].PSBlock = new byte[0]; objupdate.ObjectData[0].Text = new byte[0]; objupdate.ObjectData[0].TextColor = new byte[4]; objupdate.ObjectData[0].JointAxisOrAnchor = new LLVector3(0,0,0); @@ -232,7 +287,6 @@ namespace OpenSim.world objupdate.ObjectData[0].ExtraParams = new byte[1]; objupdate.ObjectData[0].MediaURL = new byte[0]; objupdate.ObjectData[0].NameValue = new byte[0]; - objupdate.ObjectData[0].PSBlock = new byte[0]; objupdate.ObjectData[0].Text = new byte[0]; objupdate.ObjectData[0].TextColor = new byte[4]; objupdate.ObjectData[0].JointAxisOrAnchor = new LLVector3(0,0,0); @@ -291,7 +345,6 @@ namespace OpenSim.world uint ID = this.localid; byte[] bytes = new byte[60]; - int i = 0; ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock(); dat.TextureEntry = this.OurPacket.ObjectData[0].TextureEntry; @@ -302,8 +355,18 @@ namespace OpenSim.world bytes[i++] = (byte)((ID >> 24) % 256); bytes[i++]= 0; bytes[i++]= 0; - - byte[] pb = this.position.GetBytes(); + + LLVector3 lPos; + if( this._physActor != null && this.physicsEnabled) + { + PhysicsVector pPos = this._physActor.Position; + lPos = new LLVector3( pPos.X, pPos.Y, pPos.Z); + } + else + { + lPos = this.position; + } + byte[] pb = lPos.GetBytes(); Array.Copy(pb, 0, bytes, i, pb.Length); i += 12; ushort ac = 32767; diff --git a/src/world/World.cs b/src/world/World.cs index fb78819..e1c84bc 100644 --- a/src/world/World.cs +++ b/src/world/World.cs @@ -176,9 +176,8 @@ namespace OpenSim.world ServerConsole.MainConsole.Instance.WriteLine("World.cs:AddViewerAgent() - Adding new avatar to world"); ServerConsole.MainConsole.Instance.WriteLine("World.cs:AddViewerAgent() - Starting RegionHandshake "); NewAvatar.SendRegionHandshake(this); - - NewAvatar.PhysActor = this.phyScene.AddAvatar(new PhysicsVector(NewAvatar.position.X, NewAvatar.position.Y, NewAvatar.position.Z)); - //this.Update(); // will work for now, but needs to be optimised so we don't update everything in the sim for each new user + PhysicsVector pVec = new PhysicsVector(NewAvatar.position.X, NewAvatar.position.Y, NewAvatar.position.Z); + NewAvatar.PhysActor = this.phyScene.AddAvatar(pVec); this.Entities.Add(AgentClient.AgentID, NewAvatar); } @@ -187,6 +186,10 @@ namespace OpenSim.world ServerConsole.MainConsole.Instance.WriteLine("World.cs: AddNewPrim() - Creating new prim"); Primitive prim = new Primitive(); prim.CreateFromPacket(addPacket, AgentClient.AgentID, this._primCount); + PhysicsVector pVec = new PhysicsVector(prim.position.X, prim.position.Y, prim.position.Z); + PhysicsVector pSize = new PhysicsVector( 0.25f, 0.25f, 0.25f); + //prim.PhysActor = this.phyScene.AddPrim(pVec, pSize ); + //prim.PhysicsEnabled = true; this.Entities.Add(prim.uuid, prim); this._primCount++; } -- cgit v1.1