OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
BSMaterials.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 using System;
28 using System.Collections.Generic;
29 using System.Text;
30 using System.Reflection;
31 using Nini.Config;
32 
33 namespace OpenSim.Region.PhysicsModule.BulletS
34 {
35 
36 public struct MaterialAttributes
37 {
38  // Material type values that correspond with definitions for LSL
39  public enum Material : int
40  {
41  Stone = 0,
42  Metal,
43  Glass,
44  Wood,
45  Flesh,
46  Plastic,
47  Rubber,
48  Light,
49  // Hereafter are BulletSim additions
50  Avatar,
51  NumberOfTypes // the count of types in the enum.
52  }
53 
54  // Names must be in the order of the above enum.
55  // These names must coorespond to the lower case field names in the MaterialAttributes
56  // structure as reflection is used to select the field to put the value in.
57  public static readonly string[] MaterialAttribs = { "Density", "Friction", "Restitution"};
58 
59  public MaterialAttributes(string t, float d, float f, float r)
60  {
61  type = t;
62  density = d;
63  friction = f;
64  restitution = r;
65  }
66  public string type;
67  public float density;
68  public float friction;
69  public float restitution;
70 }
71 
72 public static class BSMaterials
73 {
74  // Attributes for each material type
75  private static readonly MaterialAttributes[] Attributes;
76 
77  // Map of material name to material type code
78  public static readonly Dictionary<string, MaterialAttributes.Material> MaterialMap;
79 
80  static BSMaterials()
81  {
82  // Attribute sets for both the non-physical and physical instances of materials.
83  Attributes = new MaterialAttributes[(int)MaterialAttributes.Material.NumberOfTypes * 2];
84 
85  // Map of name to type code.
86  MaterialMap = new Dictionary<string, MaterialAttributes.Material>();
87  MaterialMap.Add("Stone", MaterialAttributes.Material.Stone);
88  MaterialMap.Add("Metal", MaterialAttributes.Material.Metal);
89  MaterialMap.Add("Glass", MaterialAttributes.Material.Glass);
90  MaterialMap.Add("Wood", MaterialAttributes.Material.Wood);
91  MaterialMap.Add("Flesh", MaterialAttributes.Material.Flesh);
92  MaterialMap.Add("Plastic", MaterialAttributes.Material.Plastic);
93  MaterialMap.Add("Rubber", MaterialAttributes.Material.Rubber);
94  MaterialMap.Add("Light", MaterialAttributes.Material.Light);
95  MaterialMap.Add("Avatar", MaterialAttributes.Material.Avatar);
96  }
97 
98  // This is where all the default material attributes are defined.
99  public static void InitializeFromDefaults(ConfigurationParameters parms)
100  {
101  // Values from http://wiki.secondlife.com/wiki/PRIM_MATERIAL
102  float dDensity = parms.defaultDensity;
103  float dFriction = parms.defaultFriction;
104  float dRestitution = parms.defaultRestitution;
105  Attributes[(int)MaterialAttributes.Material.Stone] =
106  new MaterialAttributes("stone",dDensity, 0.8f, 0.4f);
107  Attributes[(int)MaterialAttributes.Material.Metal] =
108  new MaterialAttributes("metal",dDensity, 0.3f, 0.4f);
109  Attributes[(int)MaterialAttributes.Material.Glass] =
110  new MaterialAttributes("glass",dDensity, 0.2f, 0.7f);
111  Attributes[(int)MaterialAttributes.Material.Wood] =
112  new MaterialAttributes("wood",dDensity, 0.6f, 0.5f);
113  Attributes[(int)MaterialAttributes.Material.Flesh] =
114  new MaterialAttributes("flesh",dDensity, 0.9f, 0.3f);
115  Attributes[(int)MaterialAttributes.Material.Plastic] =
116  new MaterialAttributes("plastic",dDensity, 0.4f, 0.7f);
117  Attributes[(int)MaterialAttributes.Material.Rubber] =
118  new MaterialAttributes("rubber",dDensity, 0.9f, 0.9f);
119  Attributes[(int)MaterialAttributes.Material.Light] =
120  new MaterialAttributes("light",dDensity, dFriction, dRestitution);
121  Attributes[(int)MaterialAttributes.Material.Avatar] =
122  new MaterialAttributes("avatar",3.5f, 0.2f, 0f);
123 
124  Attributes[(int)MaterialAttributes.Material.Stone + (int)MaterialAttributes.Material.NumberOfTypes] =
125  new MaterialAttributes("stonePhysical",dDensity, 0.8f, 0.4f);
126  Attributes[(int)MaterialAttributes.Material.Metal + (int)MaterialAttributes.Material.NumberOfTypes] =
127  new MaterialAttributes("metalPhysical",dDensity, 0.3f, 0.4f);
128  Attributes[(int)MaterialAttributes.Material.Glass + (int)MaterialAttributes.Material.NumberOfTypes] =
129  new MaterialAttributes("glassPhysical",dDensity, 0.2f, 0.7f);
130  Attributes[(int)MaterialAttributes.Material.Wood + (int)MaterialAttributes.Material.NumberOfTypes] =
131  new MaterialAttributes("woodPhysical",dDensity, 0.6f, 0.5f);
132  Attributes[(int)MaterialAttributes.Material.Flesh + (int)MaterialAttributes.Material.NumberOfTypes] =
133  new MaterialAttributes("fleshPhysical",dDensity, 0.9f, 0.3f);
134  Attributes[(int)MaterialAttributes.Material.Plastic + (int)MaterialAttributes.Material.NumberOfTypes] =
135  new MaterialAttributes("plasticPhysical",dDensity, 0.4f, 0.7f);
136  Attributes[(int)MaterialAttributes.Material.Rubber + (int)MaterialAttributes.Material.NumberOfTypes] =
137  new MaterialAttributes("rubberPhysical",dDensity, 0.9f, 0.9f);
138  Attributes[(int)MaterialAttributes.Material.Light + (int)MaterialAttributes.Material.NumberOfTypes] =
139  new MaterialAttributes("lightPhysical",dDensity, dFriction, dRestitution);
140  Attributes[(int)MaterialAttributes.Material.Avatar + (int)MaterialAttributes.Material.NumberOfTypes] =
141  new MaterialAttributes("avatarPhysical",3.5f, 0.2f, 0f);
142  }
143 
144  // Under the [BulletSim] section, one can change the individual material
145  // attribute values. The format of the configuration parameter is:
146  // <materialName><Attribute>["Physical"] = floatValue
147  // For instance:
148  // [BulletSim]
149  // StoneFriction = 0.2
150  // FleshRestitutionPhysical = 0.8
151  // Materials can have different parameters for their static and
152  // physical instantiations. When setting the non-physical value,
153  // both values are changed. Setting the physical value only changes
154  // the physical value.
155  public static void InitializefromParameters(IConfig pConfig)
156  {
157  foreach (KeyValuePair<string, MaterialAttributes.Material> kvp in MaterialMap)
158  {
159  string matName = kvp.Key;
160  foreach (string attribName in MaterialAttributes.MaterialAttribs)
161  {
162  string paramName = matName + attribName;
163  if (pConfig.Contains(paramName))
164  {
165  float paramValue = pConfig.GetFloat(paramName);
166  SetAttributeValue((int)kvp.Value, attribName, paramValue);
167  // set the physical value also
168  SetAttributeValue((int)kvp.Value + (int)MaterialAttributes.Material.NumberOfTypes, attribName, paramValue);
169  }
170  paramName += "Physical";
171  if (pConfig.Contains(paramName))
172  {
173  float paramValue = pConfig.GetFloat(paramName);
174  SetAttributeValue((int)kvp.Value + (int)MaterialAttributes.Material.NumberOfTypes, attribName, paramValue);
175  }
176  }
177  }
178  }
179 
180  // Use reflection to set the value in the attribute structure.
181  private static void SetAttributeValue(int matType, string attribName, float val)
182  {
183  // Get the current attribute values for this material
184  MaterialAttributes thisAttrib = Attributes[matType];
185  // Find the field for the passed attribute name (eg, find field named 'friction')
186  FieldInfo fieldInfo = thisAttrib.GetType().GetField(attribName.ToLower());
187  if (fieldInfo != null)
188  {
189  fieldInfo.SetValue(thisAttrib, val);
190  // Copy new attributes back to array -- since MaterialAttributes is 'struct', passed by value, not reference.
191  Attributes[matType] = thisAttrib;
192  }
193  }
194 
195  // Given a material type, return a structure of attributes.
196  public static MaterialAttributes GetAttributes(MaterialAttributes.Material type, bool isPhysical)
197  {
198  int ind = (int)type;
199  if (isPhysical) ind += (int)MaterialAttributes.Material.NumberOfTypes;
200  return Attributes[ind];
201  }
202 }
203 }
MaterialAttributes(string t, float d, float f, float r)
Definition: BSMaterials.cs:59