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(StaticSpace, 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(StaticSpace, 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); q1 = q1 * q2; 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 void SetTerrain(float[] heightMap, Vector3 pOffset) { float[] _heightmap; _heightmap = new float[(((int)Constants.RegionSize + 2) * ((int)Constants.RegionSize + 2))]; uint heightmapWidth = Constants.RegionSize + 2; uint heightmapHeight = Constants.RegionSize + 2; uint heightmapWidthSamples; uint heightmapHeightSamples; heightmapWidthSamples = (uint)Constants.RegionSize + 2; heightmapHeightSamples = (uint)Constants.RegionSize + 2; const float scale = 1.0f; const float offset = 0.0f; const float thickness = 10f; const int wrap = 0; int regionsize = (int) Constants.RegionSize + 2; float hfmin = float.MaxValue; float hfmax = float.MinValue; float val; int xx; int yy; int maxXXYY = regionsize - 3; // flipping map adding one margin all around so things don't fall in edges int xt = 0; xx = 0; for (int x = 0; x < heightmapWidthSamples; x++) { if (x > 1 && xx < maxXXYY) xx++; yy = 0; for (int y = 0; y < heightmapHeightSamples; y++) { if (y > 1 && y < maxXXYY) yy += (int)Constants.RegionSize; val = heightMap[yy + xx]; _heightmap[xt + y] = val; if (hfmin > val) hfmin = val; if (hfmax < val) hfmax = val; } xt += regionsize; } lock (OdeLock) { IntPtr GroundGeom = IntPtr.Zero; if (RegionTerrain.TryGetValue(pOffset, out GroundGeom)) { RegionTerrain.Remove(pOffset); if (GroundGeom != IntPtr.Zero) { if (TerrainHeightFieldHeights.ContainsKey(GroundGeom)) { TerrainHeightFieldHeightsHandlers[GroundGeom].Free(); TerrainHeightFieldHeightsHandlers.Remove(GroundGeom); TerrainHeightFieldHeights.Remove(GroundGeom); } d.SpaceRemove(StaticSpace, GroundGeom); d.GeomDestroy(GroundGeom); } } IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); GCHandle _heightmaphandler = GCHandle.Alloc(_heightmap, GCHandleType.Pinned); d.GeomHeightfieldDataBuildSingle(HeightmapData, _heightmaphandler.AddrOfPinnedObject(), 0, heightmapWidth , heightmapHeight, (int)heightmapWidthSamples, (int)heightmapHeightSamples, scale, offset, thickness, wrap); d.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1); GroundGeom = d.CreateHeightfield(StaticSpace, 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); q1 = q1 * q2; 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 + (float)Constants.RegionSize * 0.5f - 0.5f, pOffset.Y + (float)Constants.RegionSize * 0.5f - 0.5f, 0); IntPtr testGround = IntPtr.Zero; if (RegionTerrain.TryGetValue(pOffset, out testGround)) { RegionTerrain.Remove(pOffset); } RegionTerrain.Add(pOffset, GroundGeom, GroundGeom); // TerrainHeightFieldHeights.Add(GroundGeom, ODElandMap); TerrainHeightFieldHeights.Add(GroundGeom, _heightmap); TerrainHeightFieldHeightsHandlers.Add(GroundGeom, _heightmaphandler); } }
private void MakeBody() { if (!m_isphysical) // only physical get bodies return; if (childPrim) // child prims don't get bodies; return; if (m_building) return; if (prim_geom == IntPtr.Zero) { m_log.Warn("[PHYSICS]: Unable to link the linkset. Root has no geom yet"); return; } if (Body != IntPtr.Zero) { d.BodyDestroy(Body); Body = IntPtr.Zero; m_log.Warn("[PHYSICS]: MakeBody called having a body"); } d.Matrix3 mymat = new d.Matrix3(); d.Quaternion myrot = new d.Quaternion(); d.Mass objdmass = new d.Mass { }; Body = d.BodyCreate(_parent_scene.world); DMassDup(ref primdMass, out objdmass); // rotate inertia myrot.X = _orientation.X; myrot.Y = _orientation.Y; myrot.Z = _orientation.Z; myrot.W = _orientation.W; d.RfromQ(out mymat, ref myrot); d.MassRotate(ref objdmass, ref mymat); // set the body rotation and position d.BodySetRotation(Body, ref mymat); // recompute full object inertia if needed if (childrenPrim.Count > 0) { d.Matrix3 mat = new d.Matrix3(); d.Quaternion quat = new d.Quaternion(); d.Mass tmpdmass = new d.Mass { }; Vector3 rcm; rcm.X = _position.X + objdmass.c.X; rcm.Y = _position.Y + objdmass.c.Y; rcm.Z = _position.Z + objdmass.c.Z; lock (childrenPrim) { foreach (OdePrim prm in childrenPrim) { if (prm.prim_geom == IntPtr.Zero) { m_log.Warn("[PHYSICS]: Unable to link one of the linkset elements, skipping it. No geom yet"); continue; } DMassCopy(ref prm.primdMass, ref tmpdmass); // apply prim current rotation to inertia quat.X = prm._orientation.X; quat.Y = prm._orientation.Y; quat.Z = prm._orientation.Z; quat.W = prm._orientation.W; d.RfromQ(out mat, ref quat); d.MassRotate(ref tmpdmass, ref mat); Vector3 ppos = prm._position; ppos.X += tmpdmass.c.X - rcm.X; ppos.Y += tmpdmass.c.Y - rcm.Y; ppos.Z += tmpdmass.c.Z - rcm.Z; // refer inertia to root prim center of mass position d.MassTranslate(ref tmpdmass, ppos.X, ppos.Y, ppos.Z); d.MassAdd(ref objdmass, ref tmpdmass); // add to total object inertia // fix prim colision cats d.GeomClearOffset(prm.prim_geom); d.GeomSetBody(prm.prim_geom, Body); prm.Body = Body; d.GeomSetOffsetWorldRotation(prm.prim_geom, ref mat); // set relative rotation } } } d.GeomClearOffset(prim_geom); // make sure we don't have a hidden offset // associate root geom with body d.GeomSetBody(prim_geom, Body); d.BodySetPosition(Body, _position.X + objdmass.c.X, _position.Y + objdmass.c.Y, _position.Z + objdmass.c.Z); d.GeomSetOffsetWorldPosition(prim_geom, _position.X, _position.Y, _position.Z); d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body myrot.W = -myrot.W; d.RfromQ(out mymat, ref myrot); d.MassRotate(ref objdmass, ref mymat); d.BodySetMass(Body, ref objdmass); _mass = objdmass.mass; m_collisionCategories |= CollisionCategories.Body; m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); // disconnect from world gravity so we can apply buoyancy d.BodySetGravityMode(Body, false); d.BodySetAutoDisableFlag(Body, true); d.BodySetAutoDisableSteps(Body, body_autodisable_frames); // d.BodySetLinearDampingThreshold(Body, 0.01f); // d.BodySetAngularDampingThreshold(Body, 0.001f); d.BodySetDamping(Body, .001f, .0002f); d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); m_interpenetrationcount = 0; m_collisionscore = 0; m_disabled = false; if (m_targetSpace != _parent_scene.ActiveSpace) { if (m_targetSpace != IntPtr.Zero) { _parent_scene.waitForSpaceUnlock(m_targetSpace); if (d.SpaceQuery(m_targetSpace, prim_geom)) d.SpaceRemove(m_targetSpace, prim_geom); } m_targetSpace = _parent_scene.ActiveSpace; d.SpaceAdd(m_targetSpace, prim_geom); } lock (childrenPrim) { foreach (OdePrim prm in childrenPrim) { if (prm.prim_geom == IntPtr.Zero) continue; Vector3 ppos = prm._position; d.GeomSetOffsetWorldPosition(prm.prim_geom, ppos.X, ppos.Y, ppos.Z); // set relative position prm.m_collisionCategories |= CollisionCategories.Body; prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories); d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags); if (prm.m_targetSpace != _parent_scene.ActiveSpace) { if (prm.m_targetSpace != IntPtr.Zero) { _parent_scene.waitForSpaceUnlock(m_targetSpace); if (d.SpaceQuery(prm.m_targetSpace, prm.prim_geom)) d.SpaceRemove(prm.m_targetSpace, prm.prim_geom); } prm.m_targetSpace = _parent_scene.ActiveSpace; d.SpaceAdd(m_targetSpace, prm.prim_geom); } prm.m_disabled = false; prm.m_interpenetrationcount = 0; prm.m_collisionscore = 0; _parent_scene.addActivePrim(prm); } } // The body doesn't already have a finite rotation mode set here if ((!m_angularlock.ApproxEquals(Vector3.One, 0.0f)) && _parent == null) { createAMotor(m_angularlock); } _parent_scene.addActivePrim(this); }