/// <summary> /// This is called from within simulate but outside the locked portion /// We need to do our own locking here /// Essentially, we need to remove the prim from our space segment, whatever segment it's in. /// If there are no more prim in the segment, we need to empty (spacedestroy)the segment and reclaim memory /// that the space was using. /// </summary> /// <param name="prim"></param> internal void RemovePrimThreadLocked(ODEPrim prim) { RemCollisionEventReporting(prim); RemoveActivePrim(prim); prim.m_frozen = true; if (prim.prim_geom != IntPtr.Zero) { prim.DestroyBody(); prim.IsPhysical = false; prim.m_targetSpace = IntPtr.Zero; try { if (prim.prim_geom != IntPtr.Zero) { d.GeomDestroy(prim.prim_geom); prim.prim_geom = IntPtr.Zero; } else { MainConsole.Instance.Warn("[ODE Physics]: Unable to remove prim from physics scene"); } } catch (AccessViolationException) { MainConsole.Instance.Info( "[ODE Physics]: Couldn't remove prim from physics scene, it was already be removed."); } } if (!prim.childPrim) { lock (prim.childrenPrim) foreach (ODEPrim prm in prim.childrenPrim) RemovePrimThreadLocked(prm); } lock (_prims) _prims.Remove(prim); }
// I'm the parent // prim is the child public void ParentPrim(ODEPrim prim) { //Console.WriteLine("ParentPrim " + m_primName); if (m_localID != prim.m_localID) { DestroyBody(); lock (childrenPrim) { foreach (ODEPrim prm in prim.childrenPrim.Where(prm => !childrenPrim.Contains(prm))) { childrenPrim.Add(prm); } if (!childrenPrim.Contains(prim)) // must allow full reconstruction childrenPrim.Add(prim); //Remove old children prim.childrenPrim.Clear(); prim.childPrim = true; prim._parent = this; } if (prim.Body != IntPtr.Zero) { prim.DestroyBody(); // don't loose bodies around prim.Body = IntPtr.Zero; } MakeBody(); // full nasty reconstruction } }