OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
BSActorHover.cs
Go to the documentation of this file.
1 /*
2  * Copyright (c) Contributors, http://opensimulator.org/
3  * See CONTRIBUTORS.TXT for a full list of copyright holders.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyrightD
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the OpenSimulator Project nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 using System;
29 using System.Collections.Generic;
30 using System.Linq;
31 using System.Text;
32 
33 using OpenSim.Region.PhysicsModules.SharedBase;
34 
35 using OMV = OpenMetaverse;
36 
37 namespace OpenSim.Region.PhysicsModule.BulletS
38 {
39 public class BSActorHover : BSActor
40 {
41  private BSFMotor m_hoverMotor;
42 
43  public BSActorHover(BSScene physicsScene, BSPhysObject pObj, string actorName)
44  : base(physicsScene, pObj, actorName)
45  {
46  m_hoverMotor = null;
47  m_physicsScene.DetailLog("{0},BSActorHover,constructor", m_controllingPrim.LocalID);
48  }
49 
50  // BSActor.isActive
51  public override bool isActive
52  {
53  get { return Enabled; }
54  }
55 
56  // Release any connections and resources used by the actor.
57  // BSActor.Dispose()
58  public override void Dispose()
59  {
60  Enabled = false;
61  DeactivateHover();
62  }
63 
64  // Called when physical parameters (properties set in Bullet) need to be re-applied.
65  // Called at taint-time.
66  // BSActor.Refresh()
67  public override void Refresh()
68  {
69  m_physicsScene.DetailLog("{0},BSActorHover,refresh", m_controllingPrim.LocalID);
70 
71  // If not active any more, turn me off
72  if (!m_controllingPrim.HoverActive)
73  {
74  SetEnabled(false);
75  }
76 
77  // If the object is physically active, add the hoverer prestep action
78  if (isActive)
79  {
80  ActivateHover();
81  }
82  else
83  {
84  DeactivateHover();
85  }
86  }
87 
88  // The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...).
89  // Register a prestep action to restore physical requirements before the next simulation step.
90  // Called at taint-time.
91  // BSActor.RemoveDependencies()
92  public override void RemoveDependencies()
93  {
94  // Nothing to do for the hoverer since it is all software at pre-step action time.
95  }
96 
97  // If a hover motor has not been created, create one and start the hovering.
98  private void ActivateHover()
99  {
100  if (m_hoverMotor == null)
101  {
102  // Turning the target on
103  m_hoverMotor = new BSFMotor("BSActorHover",
104  m_controllingPrim.HoverTau, // timeScale
105  BSMotor.Infinite, // decay time scale
106  1f // efficiency
107  );
108  m_hoverMotor.SetTarget(ComputeCurrentHoverHeight());
109  m_hoverMotor.SetCurrent(m_controllingPrim.RawPosition.Z);
110  m_hoverMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG so motor will output detail log messages.
111 
112  m_physicsScene.BeforeStep += Hoverer;
113  }
114  }
115 
116  private void DeactivateHover()
117  {
118  if (m_hoverMotor != null)
119  {
120  m_physicsScene.BeforeStep -= Hoverer;
121  m_hoverMotor = null;
122  }
123  }
124 
125  // Called just before the simulation step. Update the vertical position for hoverness.
126  private void Hoverer(float timeStep)
127  {
128  // Don't do hovering while the object is selected.
129  if (!isActive)
130  return;
131 
132  m_hoverMotor.SetCurrent(m_controllingPrim.RawPosition.Z);
133  m_hoverMotor.SetTarget(ComputeCurrentHoverHeight());
134  float targetHeight = m_hoverMotor.Step(timeStep);
135 
136  // 'targetHeight' is where we'd like the Z of the prim to be at this moment.
137  // Compute the amount of force to push us there.
138  float moveForce = (targetHeight - m_controllingPrim.RawPosition.Z) * m_controllingPrim.RawMass;
139  // Undo anything the object thinks it's doing at the moment
140  moveForce = -m_controllingPrim.RawVelocity.Z * m_controllingPrim.Mass;
141 
142  m_physicsScene.PE.ApplyCentralImpulse(m_controllingPrim.PhysBody, new OMV.Vector3(0f, 0f, moveForce));
143  m_physicsScene.DetailLog("{0},BSPrim.Hover,move,targHt={1},moveForce={2},mass={3}",
144  m_controllingPrim.LocalID, targetHeight, moveForce, m_controllingPrim.RawMass);
145  }
146 
147  // Based on current position, determine what we should be hovering at now.
148  // Must recompute often. What if we walked offa cliff>
149  private float ComputeCurrentHoverHeight()
150  {
151  float ret = m_controllingPrim.HoverHeight;
152  float groundHeight = m_physicsScene.TerrainManager.GetTerrainHeightAtXYZ(m_controllingPrim.RawPosition);
153 
154  switch (m_controllingPrim.HoverType)
155  {
156  case PIDHoverType.Ground:
157  ret = groundHeight + m_controllingPrim.HoverHeight;
158  break;
159  case PIDHoverType.GroundAndWater:
160  float waterHeight = m_physicsScene.TerrainManager.GetWaterLevelAtXYZ(m_controllingPrim.RawPosition);
161  if (groundHeight > waterHeight)
162  {
163  ret = groundHeight + m_controllingPrim.HoverHeight;
164  }
165  else
166  {
167  ret = waterHeight + m_controllingPrim.HoverHeight;
168  }
169  break;
170  }
171  return ret;
172  }
173 }
174 }
OpenMetaverse OMV
BSActorHover(BSScene physicsScene, BSPhysObject pObj, string actorName)
Definition: BSActorHover.cs:43
Each physical object can have 'actors' who are pushing the object around. This can be used for hover...
Definition: BSActors.cs:118