/// <summary> /// This creates the Avatar's physical Surrogate at the position supplied /// </summary> /// <param name="npositionX"></param> /// <param name="npositionY"></param> /// <param name="npositionZ"></param> // WARNING: This MUST NOT be called outside of ProcessTaints, else we can have unsynchronized access // to ODE internals. ProcessTaints is called from within thread-locked Simulate(), so it is the only // place that is safe to call this routine AvatarGeomAndBodyCreation. private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ) { if (CAPSULE_LENGTH <= 0) { m_log.Warn("[PHYSICS]: The capsule size you specified in aurora.ini is invalid! Setting it to the smallest possible size!"); CAPSULE_LENGTH = 0.01f; } if (CAPSULE_RADIUS <= 0) { m_log.Warn("[PHYSICS]: The capsule size you specified in aurora.ini is invalid! Setting it to the smallest possible size!"); CAPSULE_RADIUS = 0.01f; } Shell = new btCapsuleShape(CAPSULE_RADIUS, CAPSULE_LENGTH); if (m_bodyPosition == null) { m_bodyPosition = new btVector3(npositionX, npositionY, npositionZ); } m_bodyPosition.setValue(npositionX, npositionY, npositionZ); if (m_bodyOrientation == null) { m_bodyOrientation = new btQuaternion(m_CapsuleOrientationAxis, (Utils.DEG_TO_RAD * 90)); } if (m_bodyTransform == null) { m_bodyTransform = new btTransform(m_bodyOrientation, m_bodyPosition); } else { m_bodyTransform.Dispose(); m_bodyTransform = new btTransform(m_bodyOrientation, m_bodyPosition); } if (m_bodyMotionState == null) { m_bodyMotionState = new btDefaultMotionState(m_bodyTransform); } else { m_bodyMotionState.setWorldTransform(m_bodyTransform); } m_mass = Mass; Body = new btRigidBody(m_mass, m_bodyMotionState, Shell); // this is used for self identification. User localID instead of body handle Body.setUserPointer(new IntPtr((int)m_localID)); if (ClosestCastResult != null) { ClosestCastResult.Dispose(); } ClosestCastResult = new ClosestNotMeRayResultCallback(Body); m_parent_scene.AddRigidBody(Body); Body.setActivationState(4); if (m_aMotor != null) { if (m_aMotor.Handle != IntPtr.Zero) { m_parent_scene.getBulletWorld().removeConstraint(m_aMotor); m_aMotor.Dispose(); } m_aMotor = null; } m_aMotor = new btGeneric6DofConstraint(Body, m_parent_scene.TerrainBody, m_parent_scene.TransZero, m_parent_scene.TransZero, false); m_aMotor.setAngularLowerLimit(m_parent_scene.VectorZero); m_aMotor.setAngularUpperLimit(m_parent_scene.VectorZero); }
public override void SetTerrain(float[] heightMap) { if (m_terrainShape != null) { DeleteTerrain(); } float hfmax = -9000; float hfmin = 90000; for (int i = 0; i < heightMap.Length; i++) { if (Single.IsNaN(heightMap[i]) || Single.IsInfinity(heightMap[i])) { heightMap[i] = 0f; } hfmin = (heightMap[i] < hfmin) ? heightMap[i] : hfmin; hfmax = (heightMap[i] > hfmax) ? heightMap[i] : hfmax; } // store this for later reference. // Note, we're storing it after we check it for anomolies above _origheightmap = heightMap; hfmin = 0; hfmax = 256; m_terrainShape = new btHeightfieldTerrainShape((int)Constants.RegionSize, (int)Constants.RegionSize, heightMap, 1.0f, hfmin, hfmax, (int)btHeightfieldTerrainShape.UPAxis.Z, (int)btHeightfieldTerrainShape.PHY_ScalarType.PHY_FLOAT, false); float AabbCenterX = Constants.RegionSize / 2f; float AabbCenterY = Constants.RegionSize / 2f; float AabbCenterZ = 0; float temphfmin, temphfmax; temphfmin = hfmin; temphfmax = hfmax; if (temphfmin < 0) { temphfmax = 0 - temphfmin; temphfmin = 0 - temphfmin; } else if (temphfmin > 0) { temphfmax = temphfmax + (0 - temphfmin); //temphfmin = temphfmin + (0 - temphfmin); } AabbCenterZ = temphfmax / 2f; if (m_terrainPosition == null) { m_terrainPosition = new btVector3(AabbCenterX, AabbCenterY, AabbCenterZ); } else { try { m_terrainPosition.setValue(AabbCenterX, AabbCenterY, AabbCenterZ); } catch (ObjectDisposedException) { m_terrainPosition = new btVector3(AabbCenterX, AabbCenterY, AabbCenterZ); } } if (m_terrainMotionState != null) { m_terrainMotionState.Dispose(); m_terrainMotionState = null; } m_terrainTransform = new btTransform(QuatIdentity, m_terrainPosition); m_terrainMotionState = new btDefaultMotionState(m_terrainTransform); TerrainBody = new btRigidBody(0, m_terrainMotionState, m_terrainShape); TerrainBody.setUserPointer((IntPtr)0); m_world.addRigidBody(TerrainBody); }
public override void SetTerrain(short[] shortheightMap) { if (m_terrainShape != null) { DeleteTerrain(); } float hfmax = 256; float hfmin = 0; // store this for later reference. // Note, we're storing it after we check it for anomolies above _origheightmap = shortheightMap; hfmin = 0; hfmax = 256; float[] heightmap = new float[m_region.RegionSizeX * m_region.RegionSizeX]; for (int i = 0; i < shortheightMap.Length; i++) { heightmap[i] = shortheightMap[i] / Constants.TerrainCompression; } m_terrainShape = new btHeightfieldTerrainShape(m_region.RegionSizeX, m_region.RegionSizeY, heightmap, 1.0f, hfmin, hfmax, (int)btHeightfieldTerrainShape.UPAxis.Z, (int)btHeightfieldTerrainShape.PHY_ScalarType.PHY_FLOAT, false); float AabbCenterX = m_region.RegionSizeX / 2f; float AabbCenterY = m_region.RegionSizeY / 2f; float AabbCenterZ = 0; float temphfmin, temphfmax; temphfmin = hfmin; temphfmax = hfmax; if (temphfmin < 0) { temphfmax = 0 - temphfmin; temphfmin = 0 - temphfmin; } else if (temphfmin > 0) { temphfmax = temphfmax + (0 - temphfmin); //temphfmin = temphfmin + (0 - temphfmin); } AabbCenterZ = temphfmax / 2f; if (m_terrainPosition == null) { m_terrainPosition = new btVector3(AabbCenterX, AabbCenterY, AabbCenterZ); } else { try { m_terrainPosition.setValue(AabbCenterX, AabbCenterY, AabbCenterZ); } catch (ObjectDisposedException) { m_terrainPosition = new btVector3(AabbCenterX, AabbCenterY, AabbCenterZ); } } if (m_terrainMotionState != null) { m_terrainMotionState.Dispose(); m_terrainMotionState = null; } m_terrainTransform = new btTransform(QuatIdentity, m_terrainPosition); m_terrainMotionState = new btDefaultMotionState(m_terrainTransform); TerrainBody = new btRigidBody(0, m_terrainMotionState, m_terrainShape); TerrainBody.setUserPointer((IntPtr)0); m_world.addRigidBody(TerrainBody); }