/// <summary> /// Add a child prim to this parent prim. /// </summary> /// <param name="prim">Child prim</param> public void AddChildPrim(OdePrim prim) { //Console.WriteLine("AddChildPrim " + Name); if (this.m_localID != prim.m_localID) { if (Body == IntPtr.Zero) { Body = d.BodyCreate(_parent_scene.world); setMass(); } if (Body != IntPtr.Zero) { lock (childrenPrim) { if (!childrenPrim.Contains(prim)) { //Console.WriteLine("childrenPrim.Add " + prim); childrenPrim.Add(prim); foreach (OdePrim prm in childrenPrim) { d.Mass m2; d.MassSetZero(out m2); d.MassSetBoxTotal(out m2, prim.CalculateMass(), prm._size.X, prm._size.Y, prm._size.Z); d.Quaternion quat = new d.Quaternion(); quat.W = prm._orientation.W; quat.X = prm._orientation.X; quat.Y = prm._orientation.Y; quat.Z = prm._orientation.Z; d.Matrix3 mat = new d.Matrix3(); d.RfromQ(out mat, ref quat); d.MassRotate(ref m2, ref mat); d.MassTranslate(ref m2, Position.X - prm.Position.X, Position.Y - prm.Position.Y, Position.Z - prm.Position.Z); d.MassAdd(ref pMass, ref m2); } foreach (OdePrim prm in childrenPrim) { prm.m_collisionCategories |= CollisionCategories.Body; prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); if (prm.prim_geom == IntPtr.Zero) { m_log.WarnFormat( "[PHYSICS]: Unable to link one of the linkset elements {0} for parent {1}. No geom yet", prm.Name, prim.Name); continue; } //Console.WriteLine(" GeomSetCategoryBits 1: " + prm.prim_geom + " - " + (int)prm.m_collisionCategories + " for " + Name); d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories); d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags); d.Quaternion quat = new d.Quaternion(); quat.W = prm._orientation.W; quat.X = prm._orientation.X; quat.Y = prm._orientation.Y; quat.Z = prm._orientation.Z; d.Matrix3 mat = new d.Matrix3(); d.RfromQ(out mat, ref quat); if (Body != IntPtr.Zero) { d.GeomSetBody(prm.prim_geom, Body); prm.childPrim = true; d.GeomSetOffsetWorldPosition(prm.prim_geom, prm.Position.X , prm.Position.Y, prm.Position.Z); //d.GeomSetOffsetPosition(prim.prim_geom, // (Position.X - prm.Position.X) - pMass.c.X, // (Position.Y - prm.Position.Y) - pMass.c.Y, // (Position.Z - prm.Position.Z) - pMass.c.Z); d.GeomSetOffsetWorldRotation(prm.prim_geom, ref mat); //d.GeomSetOffsetRotation(prm.prim_geom, ref mat); d.MassTranslate(ref pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z); d.BodySetMass(Body, ref pMass); } else { m_log.DebugFormat("[PHYSICS]: {0} ain't got no boooooooooddy, no body", Name); } prm.m_interpenetrationcount = 0; prm.m_collisionscore = 0; prm.m_disabled = false; // The body doesn't already have a finite rotation mode set here if ((!m_angularlock.ApproxEquals(Vector3.Zero, 0f)) && _parent == null) { prm.createAMotor(m_angularlock); } prm.Body = Body; _parent_scene.addActivePrim(prm); } m_collisionCategories |= CollisionCategories.Body; m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); //Console.WriteLine("GeomSetCategoryBits 2: " + prim_geom + " - " + (int)m_collisionCategories + " for " + Name); d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); //Console.WriteLine(" Post GeomSetCategoryBits 2"); d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); d.Quaternion quat2 = new d.Quaternion(); quat2.W = _orientation.W; quat2.X = _orientation.X; quat2.Y = _orientation.Y; quat2.Z = _orientation.Z; d.Matrix3 mat2 = new d.Matrix3(); d.RfromQ(out mat2, ref quat2); d.GeomSetBody(prim_geom, Body); d.GeomSetOffsetWorldPosition(prim_geom, Position.X - pMass.c.X, Position.Y - pMass.c.Y, Position.Z - pMass.c.Z); //d.GeomSetOffsetPosition(prim.prim_geom, // (Position.X - prm.Position.X) - pMass.c.X, // (Position.Y - prm.Position.Y) - pMass.c.Y, // (Position.Z - prm.Position.Z) - pMass.c.Z); //d.GeomSetOffsetRotation(prim_geom, ref mat2); d.MassTranslate(ref pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z); d.BodySetMass(Body, ref pMass); d.BodySetAutoDisableFlag(Body, true); d.BodySetAutoDisableSteps(Body, body_autodisable_frames); m_interpenetrationcount = 0; m_collisionscore = 0; m_disabled = false; // The body doesn't already have a finite rotation mode set here if ((!m_angularlock.ApproxEquals(Vector3.Zero, 0f)) && _parent == null) { createAMotor(m_angularlock); } d.BodySetPosition(Body, Position.X, Position.Y, Position.Z); if (m_vehicle.Type != Vehicle.TYPE_NONE) m_vehicle.Enable(Body, _parent_scene); _parent_scene.addActivePrim(this); } } } } }
public void randomizeWater(float baseheight) { const uint heightmapWidth = m_regionWidth + 2; const uint heightmapHeight = m_regionHeight + 2; const uint heightmapWidthSamples = m_regionWidth + 2; const uint heightmapHeightSamples = m_regionHeight + 2; const float scale = 1.0f; const float offset = 0.0f; const float thickness = 2.9f; const int wrap = 0; for (int i = 0; i < (258 * 258); i++) { _watermap[i] = (baseheight-0.1f) + ((float)fluidRandomizer.Next(1,9) / 10f); // m_log.Info((baseheight - 0.1f) + ((float)fluidRandomizer.Next(1, 9) / 10f)); } lock (OdeLock) { if (WaterGeom != IntPtr.Zero) { d.SpaceRemove(space, WaterGeom); } IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); d.GeomHeightfieldDataBuildSingle(HeightmapData, _watermap, 0, heightmapWidth, heightmapHeight, (int)heightmapWidthSamples, (int)heightmapHeightSamples, scale, offset, thickness, wrap); d.GeomHeightfieldDataSetBounds(HeightmapData, m_regionWidth, m_regionHeight); WaterGeom = d.CreateHeightfield(space, HeightmapData, 1); if (WaterGeom != IntPtr.Zero) { d.GeomSetCategoryBits(WaterGeom, (int)(CollisionCategories.Water)); d.GeomSetCollideBits(WaterGeom, (int)(CollisionCategories.Space)); } geom_name_map[WaterGeom] = "Water"; d.Matrix3 R = new d.Matrix3(); Quaternion q1 = Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), 1.5707f); Quaternion q2 = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), 1.5707f); //Axiom.Math.Quaternion q3 = Axiom.Math.Quaternion.FromAngleAxis(3.14f, new Axiom.Math.Vector3(0, 0, 1)); q1 = q1 * q2; //q1 = q1 * q3; Vector3 v3; float angle; q1.GetAxisAngle(out v3, out angle); d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); d.GeomSetRotation(WaterGeom, ref R); d.GeomSetPosition(WaterGeom, 128, 128, 0); } }
public override void SetTerrain(float[] heightMap) { for (int i = 0; i < 65536; i++) { this._heightmap[i] = (double)heightMap[i]; } IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); d.GeomHeightfieldDataBuildDouble(HeightmapData, _heightmap, 0, 256, 256, 256, 256, 1.0f, 0.0f, 2.0f, 0); d.GeomHeightfieldDataSetBounds(HeightmapData, 256, 256); LandGeom = d.CreateHeightfield(space, HeightmapData, 1); d.Matrix3 R = new d.Matrix3(); Axiom.MathLib.Quaternion q1 =Axiom.MathLib.Quaternion.FromAngleAxis(1.5707f, new Axiom.MathLib.Vector3(1,0,0)); Axiom.MathLib.Quaternion q2 =Axiom.MathLib.Quaternion.FromAngleAxis(1.5707f, new Axiom.MathLib.Vector3(0,1,0)); //Axiom.MathLib.Quaternion q3 = Axiom.MathLib.Quaternion.FromAngleAxis(3.14f, new Axiom.MathLib.Vector3(0, 0, 1)); q1 = q1 * q2; //q1 = q1 * q3; Axiom.MathLib.Vector3 v3 = new Axiom.MathLib.Vector3(); float angle = 0; q1.ToAngleAxis(ref angle, ref v3); d.RFromAxisAndAngle(out R, v3.x, v3.y, v3.z, angle); d.GeomSetRotation(LandGeom, ref R); d.GeomSetPosition(LandGeom, 128, 128, 0); }
public void SetTerrain(float[] heightMap, Vector3 pOffset) { // this._heightmap[i] = (double)heightMap[i]; // dbm (danx0r) -- creating a buffer zone of one extra sample all around //_origheightmap = heightMap; float[] _heightmap; // zero out a heightmap array float array (single dimension [flattened])) //if ((int)Constants.RegionSize == 256) // _heightmap = new float[514 * 514]; //else _heightmap = new float[(((int)Constants.RegionSize + 2) * ((int)Constants.RegionSize + 2))]; uint heightmapWidth = Constants.RegionSize + 1; uint heightmapHeight = Constants.RegionSize + 1; uint heightmapWidthSamples; uint heightmapHeightSamples; //if (((int)Constants.RegionSize) == 256) //{ // heightmapWidthSamples = 2 * (uint)Constants.RegionSize + 2; // heightmapHeightSamples = 2 * (uint)Constants.RegionSize + 2; // heightmapWidth++; // heightmapHeight++; //} //else //{ heightmapWidthSamples = (uint)Constants.RegionSize + 1; heightmapHeightSamples = (uint)Constants.RegionSize + 1; //} const float scale = 1.0f; const float offset = 0.0f; const float thickness = 0.2f; const int wrap = 0; int regionsize = (int) Constants.RegionSize + 2; //Double resolution //if (((int)Constants.RegionSize) == 256) // heightMap = ResizeTerrain512Interpolation(heightMap); // if (((int)Constants.RegionSize) == 256 && (int)Constants.RegionSize == 256) // regionsize = 512; float hfmin = 2000; float hfmax = -2000; for (int x = 0; x < heightmapWidthSamples; x++) { for (int y = 0; y < heightmapHeightSamples; y++) { int xx = Util.Clip(x - 1, 0, regionsize - 1); int yy = Util.Clip(y - 1, 0, regionsize - 1); float val= heightMap[yy * (int)Constants.RegionSize + xx]; _heightmap[x * ((int)Constants.RegionSize + 2) + y] = val; hfmin = (val < hfmin) ? val : hfmin; hfmax = (val > hfmax) ? val : hfmax; } } lock (OdeLock) { IntPtr GroundGeom = IntPtr.Zero; if (RegionTerrain.TryGetValue(pOffset, out GroundGeom)) { RegionTerrain.Remove(pOffset); if (GroundGeom != IntPtr.Zero) { if (TerrainHeightFieldHeights.ContainsKey(GroundGeom)) { TerrainHeightFieldHeights.Remove(GroundGeom); } d.SpaceRemove(space, GroundGeom); d.GeomDestroy(GroundGeom); } } IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); d.GeomHeightfieldDataBuildSingle(HeightmapData, _heightmap, 0, heightmapWidth + 1, heightmapHeight + 1, (int)heightmapWidthSamples + 1, (int)heightmapHeightSamples + 1, scale, offset, thickness, wrap); d.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1); GroundGeom = d.CreateHeightfield(space, HeightmapData, 1); if (GroundGeom != IntPtr.Zero) { d.GeomSetCategoryBits(GroundGeom, (int)(CollisionCategories.Land)); d.GeomSetCollideBits(GroundGeom, (int)(CollisionCategories.Space)); } geom_name_map[GroundGeom] = "Terrain"; d.Matrix3 R = new d.Matrix3(); Quaternion q1 = Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), 1.5707f); Quaternion q2 = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), 1.5707f); //Axiom.Math.Quaternion q3 = Axiom.Math.Quaternion.FromAngleAxis(3.14f, new Axiom.Math.Vector3(0, 0, 1)); q1 = q1 * q2; //q1 = q1 * q3; Vector3 v3; float angle; q1.GetAxisAngle(out v3, out angle); d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); d.GeomSetRotation(GroundGeom, ref R); d.GeomSetPosition(GroundGeom, (pOffset.X + ((int)Constants.RegionSize * 0.5f)) - 1, (pOffset.Y + ((int)Constants.RegionSize * 0.5f)) - 1, 0); IntPtr testGround = IntPtr.Zero; if (RegionTerrain.TryGetValue(pOffset, out testGround)) { RegionTerrain.Remove(pOffset); } RegionTerrain.Add(pOffset, GroundGeom, GroundGeom); TerrainHeightFieldHeights.Add(GroundGeom,_heightmap); } }
public override void SetTerrain(float[] heightMap) { // this._heightmap[i] = (double)heightMap[i]; // dbm (danx0r) -- creating a buffer zone of one extra sample all around _origheightmap = heightMap; // Used for Fly height. Kitto Flora const uint heightmapWidth = m_regionWidth + 2; const uint heightmapHeight = m_regionHeight + 2; const uint heightmapWidthSamples = 2*m_regionWidth + 2; const uint heightmapHeightSamples = 2*m_regionHeight + 2; const float scale = 1.0f; const float offset = 0.0f; const float thickness = 0.2f; const int wrap = 0; //Double resolution heightMap = ResizeTerrain512Interpolation(heightMap); float hfmin = 2000; float hfmax = -2000; for (int x = 0; x < heightmapWidthSamples; x++) { for (int y = 0; y < heightmapHeightSamples; y++) { int xx = Util.Clip(x - 1, 0, 511); int yy = Util.Clip(y - 1, 0, 511); float val = heightMap[yy*512 + xx]; _heightmap[x*heightmapHeightSamples + y] = val; hfmin = (val < hfmin) ? val : hfmin; hfmax = (val > hfmax) ? val : hfmax; } } lock (OdeLock) { if (LandGeom != IntPtr.Zero) { d.SpaceRemove(space, LandGeom); } IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); d.GeomHeightfieldDataBuildSingle(HeightmapData, _heightmap, 0, heightmapWidth, heightmapHeight, (int) heightmapWidthSamples, (int) heightmapHeightSamples, scale, offset, thickness, wrap); d.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1 , hfmax + 1); LandGeom = d.CreateHeightfield(space, HeightmapData, 1); if (LandGeom != IntPtr.Zero) { d.GeomSetCategoryBits(LandGeom, (int)(CollisionCategories.Land)); d.GeomSetCollideBits(LandGeom, (int)(CollisionCategories.Space)); } geom_name_map[LandGeom] = "Terrain"; d.Matrix3 R = new d.Matrix3(); Quaternion q1 = Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), 1.5707f); Quaternion q2 = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), 1.5707f); //Axiom.Math.Quaternion q3 = Axiom.Math.Quaternion.FromAngleAxis(3.14f, new Axiom.Math.Vector3(0, 0, 1)); q1 = q1*q2; //q1 = q1 * q3; Vector3 v3; float angle; q1.GetAxisAngle(out v3, out angle); d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); d.GeomSetRotation(LandGeom, ref R); d.GeomSetPosition(LandGeom, 128, 128, 0); } }