diff options
Diffstat (limited to 'OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs')
-rw-r--r-- | OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs | 643 |
1 files changed, 144 insertions, 499 deletions
diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs index 0a4ebe4..514074c 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs | |||
@@ -163,6 +163,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
163 | private bool m_isphysical; | 163 | private bool m_isphysical; |
164 | private bool m_isSelected; | 164 | private bool m_isSelected; |
165 | 165 | ||
166 | private bool m_NoColide; // for now only for internal use for bad meshs | ||
167 | |||
166 | internal bool m_isVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively | 168 | internal bool m_isVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively |
167 | 169 | ||
168 | private bool m_throttleUpdates; | 170 | private bool m_throttleUpdates; |
@@ -253,7 +255,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
253 | private float m_verticalAttractionEfficiency = 1.0f; // damped | 255 | private float m_verticalAttractionEfficiency = 1.0f; // damped |
254 | private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor. | 256 | private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor. |
255 | 257 | ||
256 | SerialControl m_taintserial = null; | 258 | // SerialControl m_taintserial = null; |
257 | object m_taintvehicledata = null; | 259 | object m_taintvehicledata = null; |
258 | 260 | ||
259 | public void DoSetVehicle() | 261 | public void DoSetVehicle() |
@@ -309,410 +311,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
309 | m_taintvehicledata = vdata; | 311 | m_taintvehicledata = vdata; |
310 | _parent_scene.AddPhysicsActorTaint(this); | 312 | _parent_scene.AddPhysicsActorTaint(this); |
311 | } | 313 | } |
312 | |||
313 | public override byte[] Serialize(bool PhysIsRunning) | ||
314 | { | ||
315 | SerialControl sc = new SerialControl(); | ||
316 | |||
317 | lock (sc.alock) | ||
318 | { | ||
319 | if (PhysIsRunning) | ||
320 | { | ||
321 | m_taintserial = sc; | ||
322 | |||
323 | if (!Monitor.Wait(sc.alock, 1000)) | ||
324 | { | ||
325 | m_log.Error("[chOde] prim data serialization timed out"); | ||
326 | m_taintserial = null; | ||
327 | return new byte[0]; | ||
328 | } | ||
329 | } | ||
330 | else | ||
331 | DoSerialize(sc); | ||
332 | } | ||
333 | |||
334 | return sc.data; | ||
335 | } | ||
336 | |||
337 | public void DoSerialize(SerialControl sc) | ||
338 | { | ||
339 | wstreamer st = new wstreamer(); | ||
340 | Vector3 vtmp; | ||
341 | |||
342 | ushort version = 2; | ||
343 | if (!BitConverter.IsLittleEndian) | ||
344 | version |= 1; | ||
345 | st.Wushort(version); //version lower bit codes endian type for future use | ||
346 | |||
347 | // compact booleans in a ushort | ||
348 | ushort flags = 0; | ||
349 | |||
350 | if (m_isphysical) // this should be true for now | ||
351 | flags |= 1; | ||
352 | if (m_isSelected) | ||
353 | flags |= 2; | ||
354 | if (m_isVolumeDetect) | ||
355 | flags |= 4; | ||
356 | if (m_disabled) | ||
357 | flags |= 8; | ||
358 | if (m_collidesWater) | ||
359 | flags |= 16; | ||
360 | if (m_collidesLand) | ||
361 | flags |= 32; | ||
362 | if (m_usePID) | ||
363 | flags |= 64; | ||
364 | if (m_useAPID) | ||
365 | flags |= 128; | ||
366 | if (m_useHoverPID) | ||
367 | flags |= 256; | ||
368 | if (m_throttleUpdates) | ||
369 | flags |= 512; | ||
370 | |||
371 | st.Wushort(flags); | ||
372 | |||
373 | st.Wvector3(_size); | ||
374 | st.Wint(m_material); | ||
375 | st.Wfloat(m_density); | ||
376 | st.Wfloat(0); // future gravity mod V3 | ||
377 | st.Wfloat(0); // future friction V3 | ||
378 | st.Wfloat(0); // future bounce V3 | ||
379 | |||
380 | // st.Wuint((uint)m_collisionCategories); | ||
381 | // st.Wuint((uint)m_collisionFlags); | ||
382 | |||
383 | if (_parent == null) | ||
384 | { | ||
385 | st.Wvector3(_position); // ?? | ||
386 | st.Wquat(_orientation); | ||
387 | } | ||
388 | else // for childs save offsets | ||
389 | { | ||
390 | Quaternion to; | ||
391 | Quaternion ipo = Quaternion.Inverse(_parent.Orientation); | ||
392 | |||
393 | if (m_isphysical && prim_geom != IntPtr.Zero) | ||
394 | { | ||
395 | d.Vector3 dvt; | ||
396 | d.GeomCopyPosition(prim_geom, out dvt); | ||
397 | |||
398 | vtmp.X = dvt.X; | ||
399 | vtmp.Y = dvt.Y; | ||
400 | vtmp.Z = dvt.Z; | ||
401 | |||
402 | d.Quaternion dqt; | ||
403 | d.GeomCopyQuaternion(prim_geom, out dqt); | ||
404 | |||
405 | to.X = dqt.X; | ||
406 | to.Y = dqt.Y; | ||
407 | to.Z = dqt.Z; | ||
408 | to.W = dqt.W; // rotation in world | ||
409 | } | ||
410 | else | ||
411 | { | ||
412 | vtmp = _position; | ||
413 | to = _orientation; | ||
414 | } | ||
415 | |||
416 | vtmp -= _parent.Position; // offset in world | ||
417 | vtmp *= ipo; // offset in local | ||
418 | st.Wvector3(vtmp); | ||
419 | |||
420 | ipo *= to; // own rotation | ||
421 | st.Wquat(ipo); | ||
422 | } | ||
423 | |||
424 | st.Wvector3(_velocity); | ||
425 | st.Wvector3(m_rotationalVelocity); | ||
426 | st.Wvector3(_acceleration); | ||
427 | st.Wvector3(m_rotateEnable); | ||
428 | |||
429 | vtmp = Vector3.Zero; | ||
430 | for (int i = 0; i < m_forcelist.Count; i++) | ||
431 | { | ||
432 | |||
433 | vtmp += (m_forcelist[i] * 100); | ||
434 | } | ||
435 | |||
436 | st.Wvector3(vtmp); // force acc | ||
437 | |||
438 | vtmp = Vector3.Zero; | ||
439 | for (int i = 0; i < m_angularforcelist.Count; i++) | ||
440 | { | ||
441 | vtmp += (m_angularforcelist[i] * 100); | ||
442 | } | ||
443 | |||
444 | st.Wvector3(vtmp); // angular force acc | ||
445 | |||
446 | st.Wvector3(m_PIDTarget); | ||
447 | st.Wfloat(m_PIDTau); | ||
448 | st.Wfloat(PID_D); | ||
449 | st.Wfloat(PID_G); | ||
450 | st.Wquat(m_APIDTarget); | ||
451 | st.Wfloat(m_APIDStrength); | ||
452 | st.Wfloat(m_APIDDamping); | ||
453 | st.Wfloat(m_APIDdamper); | ||
454 | |||
455 | st.Wint((int)m_PIDHoverType); | ||
456 | st.Wfloat(m_PIDHoverHeight); | ||
457 | st.Wfloat(m_PIDHoverTau); | ||
458 | st.Wfloat(m_targetHoverHeight); | ||
459 | |||
460 | st.Wfloat(m_groundHeight); | ||
461 | st.Wfloat(m_waterHeight); | ||
462 | |||
463 | st.Wfloat(m_buoyancy); | ||
464 | |||
465 | // this must be last since type none ends stream | ||
466 | if (m_type == Vehicle.TYPE_NONE) | ||
467 | st.Wint((int)Vehicle.TYPE_NONE); | ||
468 | else | ||
469 | { | ||
470 | st.Wint((int)m_type); | ||
471 | |||
472 | st.Wquat(Quaternion.Identity); //m_referenceFrame | ||
473 | |||
474 | st.Wint((int)m_flags); | ||
475 | |||
476 | st.Wvector3(m_linearMotorDirection); | ||
477 | st.Wfloat( | ||
478 | (float)Math.Sqrt(m_lLinMotorDVel.LengthSquared() / m_linearMotorDirection.LengthSquared())); | ||
479 | |||
480 | st.Wvector3(m_linearFrictionTimescale); | ||
481 | st.Wfloat(m_linearMotorDecayTimescale); | ||
482 | st.Wfloat(m_linearMotorTimescale); | ||
483 | st.Wvector3(new Vector3(0, 0, 0)); //m_linearMotorOffset); | ||
484 | |||
485 | st.Wvector3(m_angularMotorDirection); | ||
486 | st.Wfloat((float)Math.Sqrt(m_angularMotorDVel.LengthSquared() / m_angularMotorDirection.LengthSquared())); | ||
487 | |||
488 | st.Wvector3(m_angularFrictionTimescale); | ||
489 | st.Wfloat(m_angularMotorDecayTimescale); | ||
490 | st.Wfloat(m_angularMotorTimescale); | ||
491 | |||
492 | st.Wfloat(0); //m_linearDeflectionEfficiency); | ||
493 | st.Wfloat(1000); //m_linearDeflectionTimescale); | ||
494 | |||
495 | st.Wfloat(0); //m_angularDeflectionEfficiency); | ||
496 | st.Wfloat(120); //m_angularDeflectionTimescale); | ||
497 | |||
498 | st.Wfloat(0); // m_bankingEfficiency); | ||
499 | st.Wfloat(0); //m_bankingMix); | ||
500 | st.Wfloat(1000); //m_bankingTimescale); | ||
501 | |||
502 | st.Wfloat(m_VhoverHeight); | ||
503 | st.Wfloat(0.5f); //m_VhoverEfficiency); | ||
504 | st.Wfloat(m_VhoverTimescale); | ||
505 | |||
506 | st.Wfloat(m_VehicleBuoyancy); | ||
507 | |||
508 | st.Wfloat(m_verticalAttractionEfficiency); | ||
509 | st.Wfloat(m_verticalAttractionTimescale); | ||
510 | } | ||
511 | sc.data = st.close(); | ||
512 | m_taintserial = null; | ||
513 | Monitor.PulseAll(sc.alock); | ||
514 | } | ||
515 | |||
516 | public bool DeSerialize(byte[] data) | ||
517 | { | ||
518 | rstreamer st = new rstreamer(data); | ||
519 | |||
520 | int version =st.Rushort(); //version | ||
521 | |||
522 | // merge booleans in a ushort | ||
523 | ushort flags = st.Rushort(); | ||
524 | if ((flags & 1) != 0) | ||
525 | m_isphysical = true; | ||
526 | if ((flags & 2) != 0) | ||
527 | m_taintselected = true; | ||
528 | if ((flags & 4) != 0) | ||
529 | m_isVolumeDetect = true; | ||
530 | if ((flags & 8) != 0) | ||
531 | m_taintdisable = true; | ||
532 | if ((flags & 16) != 0) | ||
533 | m_taintCollidesWater = true; | ||
534 | if ((flags & 32) != 0) | ||
535 | m_collidesLand = true; | ||
536 | if ((flags & 64) != 0) | ||
537 | m_usePID = true; | ||
538 | if ((flags & 128) != 0) | ||
539 | m_useAPID = true; | ||
540 | if ((flags & 256) != 0) | ||
541 | m_useHoverPID = true; | ||
542 | if ((flags & 512) != 0) | ||
543 | m_throttleUpdates = true; | ||
544 | |||
545 | _size = st.Rvector3(); | ||
546 | m_taintsize = _size; | ||
547 | |||
548 | m_material= st.Rint(); | ||
549 | m_density = st.Rfloat(); | ||
550 | st.Rfloat(); // future gravity mod V3 | ||
551 | st.Rfloat(); // future friction V3 | ||
552 | st.Rfloat(); // future bounce V3 | ||
553 | |||
554 | // m_collisionCategories = (CollisionCategories)st.Ruint(); | ||
555 | // m_collisionFlags = (CollisionCategories) st.Ruint(); | ||
556 | |||
557 | if (m_taintparent == null) | ||
558 | { | ||
559 | st.Rvector3(); // ignore old position sop/sog as to tell the new one | ||
560 | m_taintrot = st.Rquat(); // | ||
561 | _orientation = m_taintrot; | ||
562 | } | ||
563 | else | ||
564 | { | ||
565 | m_taintrot = _parent.Orientation; | ||
566 | m_taintposition = st.Rvector3(); // ?? | ||
567 | _position = m_taintposition; | ||
568 | |||
569 | m_taintposition *= m_taintrot; | ||
570 | m_taintposition += _parent.Position; | ||
571 | |||
572 | m_taintrot *= st.Rquat(); // | ||
573 | _orientation = m_taintrot; | ||
574 | } | ||
575 | |||
576 | m_taintVelocity = st.Rvector3(); | ||
577 | m_rotationalVelocity = st.Rvector3(); | ||
578 | |||
579 | _acceleration = st.Rvector3(); | ||
580 | m_rotateEnableRequest = st.Rvector3(); | ||
581 | m_rotateEnableUpdate = true; | ||
582 | |||
583 | Vector3 vtmp; | ||
584 | |||
585 | vtmp = st.Rvector3(); // forces acc | ||
586 | m_forcelist.Add(vtmp); | ||
587 | m_taintforce = true; | ||
588 | |||
589 | vtmp = st.Rvector3(); // angular forces acc | ||
590 | m_angularforcelist.Add(vtmp); | ||
591 | m_taintaddangularforce = true; | ||
592 | |||
593 | m_PIDTarget = st.Rvector3(); | ||
594 | m_PIDTau = st.Rfloat(); | ||
595 | PID_D = st.Rfloat(); | ||
596 | PID_G = st.Rfloat(); | ||
597 | |||
598 | m_APIDTarget = st.Rquat(); | ||
599 | m_APIDStrength = st.Rfloat(); | ||
600 | m_APIDDamping = st.Rfloat(); | ||
601 | m_APIDdamper = st.Rfloat(); | ||
602 | |||
603 | m_PIDHoverType = (PIDHoverType) st.Rint(); | ||
604 | m_PIDHoverHeight = st.Rfloat(); | ||
605 | m_PIDHoverTau = st.Rfloat(); | ||
606 | m_targetHoverHeight = st.Rfloat(); | ||
607 | |||
608 | m_groundHeight = st.Rfloat(); | ||
609 | m_waterHeight = st.Rfloat(); | ||
610 | |||
611 | m_buoyancy = st.Rfloat(); | ||
612 | |||
613 | |||
614 | // this must be last since type none ends stream | ||
615 | |||
616 | m_type = (Vehicle) st.Rint(); | ||
617 | |||
618 | if (m_type != Vehicle.TYPE_NONE) | ||
619 | { | ||
620 | float ftmp; | ||
621 | |||
622 | st.Rquat(); //m_referenceFrame | ||
623 | |||
624 | m_flags = (VehicleFlag) st.Rint(); | ||
625 | |||
626 | m_linearMotorDirection = st.Rvector3(); | ||
627 | |||
628 | ftmp = st.Rfloat(); | ||
629 | m_lLinMotorDVel = m_linearMotorDirection * ftmp; | ||
630 | |||
631 | m_linearFrictionTimescale = st.Rvector3(); | ||
632 | m_linearMotorDecayTimescale = st.Rfloat(); | ||
633 | m_linearMotorTimescale = st.Rfloat(); | ||
634 | st.Rvector3(); //m_linearMotorOffset); | ||
635 | |||
636 | m_angularMotorDirection = st.Rvector3(); | ||
637 | ftmp = st.Rfloat(); | ||
638 | m_angularMotorDVel = m_angularMotorDirection * ftmp; | ||
639 | |||
640 | m_angularFrictionTimescale = st.Rvector3(); | ||
641 | m_angularMotorDecayTimescale = st.Rfloat(); | ||
642 | m_angularMotorTimescale = st.Rfloat(); | ||
643 | |||
644 | st.Rfloat(); //m_linearDeflectionEfficiency); | ||
645 | st.Rfloat(); //m_linearDeflectionTimescale); | ||
646 | |||
647 | st.Rfloat(); //m_angularDeflectionEfficiency); | ||
648 | st.Rfloat(); //m_angularDeflectionTimescale); | ||
649 | |||
650 | st.Rfloat(); // m_bankingEfficiency); | ||
651 | st.Rfloat(); //m_bankingMix); | ||
652 | st.Rfloat(); //m_bankingTimescale); | ||
653 | |||
654 | m_VhoverHeight = st.Rfloat(); | ||
655 | st.Rfloat(); //m_VhoverEfficiency); | ||
656 | m_VhoverTimescale = st.Rfloat(); | ||
657 | |||
658 | m_VehicleBuoyancy = st.Rfloat(); | ||
659 | |||
660 | m_verticalAttractionEfficiency = st.Rfloat(); | ||
661 | m_verticalAttractionTimescale = st.Rfloat(); | ||
662 | } | ||
663 | st.close(); | ||
664 | return true; | ||
665 | } | ||
666 | |||
667 | public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, PhysicsActor parent, | ||
668 | PrimitiveBaseShape pbs, CollisionLocker dode, uint localid, byte[] sdata) | ||
669 | { | ||
670 | m_localID = localid; | ||
671 | ode = dode; | ||
672 | |||
673 | if (parent == null) | ||
674 | { | ||
675 | m_taintparent = null; | ||
676 | |||
677 | if (!pos.IsFinite()) | ||
678 | { | ||
679 | pos = new Vector3(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f), | ||
680 | parent_scene.GetTerrainHeightAtXY(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f)) + 0.5f); | ||
681 | m_log.Warn("[PHYSICS]: Got nonFinite Object create Position"); | ||
682 | } | ||
683 | |||
684 | _position = pos; | ||
685 | m_taintposition = pos; | ||
686 | } | ||
687 | else | ||
688 | m_taintparent = parent; | ||
689 | |||
690 | body_autodisable_frames = parent_scene.bodyFramesAutoDisable; | ||
691 | |||
692 | prim_geom = IntPtr.Zero; | ||
693 | |||
694 | _mesh = null; | ||
695 | m_meshfailed = false; | ||
696 | _pbs = pbs; | ||
697 | |||
698 | _parent_scene = parent_scene; | ||
699 | m_targetSpace = (IntPtr)0; | ||
700 | |||
701 | if(sdata != null && sdata.Length > 1) | ||
702 | DeSerialize(sdata); | ||
703 | |||
704 | if (m_isphysical) | ||
705 | m_targetSpace = _parent_scene.space; | ||
706 | |||
707 | _triMeshData = IntPtr.Zero; | ||
708 | |||
709 | m_primName = primName; | ||
710 | m_taintserial = null; | ||
711 | m_taintadd = true; | ||
712 | _parent_scene.AddPhysicsActorTaint(this); | ||
713 | // don't do .add() here; old geoms get recycled with the same hash | ||
714 | } | ||
715 | |||
716 | public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, Vector3 size, | 314 | public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, Vector3 size, |
717 | Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode, uint localid) | 315 | Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode, uint localid) |
718 | { | 316 | { |
@@ -776,8 +374,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
776 | } | 374 | } |
777 | 375 | ||
778 | _triMeshData = IntPtr.Zero; | 376 | _triMeshData = IntPtr.Zero; |
377 | m_NoColide = false; | ||
779 | 378 | ||
780 | m_taintserial = null; | 379 | // m_taintserial = null; |
781 | m_primName = primName; | 380 | m_primName = primName; |
782 | m_taintadd = true; | 381 | m_taintadd = true; |
783 | _parent_scene.AddPhysicsActorTaint(this); | 382 | _parent_scene.AddPhysicsActorTaint(this); |
@@ -814,7 +413,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
814 | { | 413 | { |
815 | set | 414 | set |
816 | { | 415 | { |
817 | |||
818 | //Console.WriteLine("Sel {0} {1} {2}", m_primName, value, m_isphysical); | 416 | //Console.WriteLine("Sel {0} {1} {2}", m_primName, value, m_isphysical); |
819 | // This only makes the object not collidable if the object | 417 | // This only makes the object not collidable if the object |
820 | // is physical or the object is modified somehow *IN THE FUTURE* | 418 | // is physical or the object is modified somehow *IN THE FUTURE* |
@@ -1077,7 +675,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1077 | } | 675 | } |
1078 | } | 676 | } |
1079 | 677 | ||
1080 | |||
1081 | public override bool FloatOnWater | 678 | public override bool FloatOnWater |
1082 | { | 679 | { |
1083 | set | 680 | set |
@@ -1270,7 +867,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1270 | } | 867 | } |
1271 | } | 868 | } |
1272 | 869 | ||
1273 | |||
1274 | public void SetGeom(IntPtr geom) | 870 | public void SetGeom(IntPtr geom) |
1275 | { | 871 | { |
1276 | if (prim_geom != IntPtr.Zero) | 872 | if (prim_geom != IntPtr.Zero) |
@@ -1290,9 +886,23 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1290 | { | 886 | { |
1291 | _parent_scene.geom_name_map[prim_geom] = this.m_primName; | 887 | _parent_scene.geom_name_map[prim_geom] = this.m_primName; |
1292 | _parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this; | 888 | _parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this; |
1293 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | ||
1294 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | ||
1295 | //Console.WriteLine("**** Create {2} Dicts: actor={0} name={1}", _parent_scene.actor_name_map.Count, _parent_scene.geom_name_map.Count, this.m_primName); | 889 | //Console.WriteLine("**** Create {2} Dicts: actor={0} name={1}", _parent_scene.actor_name_map.Count, _parent_scene.geom_name_map.Count, this.m_primName); |
890 | if (m_NoColide) | ||
891 | { | ||
892 | d.GeomSetCategoryBits(prim_geom, 0); | ||
893 | if (m_isphysical) | ||
894 | { | ||
895 | d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land); | ||
896 | d.GeomDisable(prim_geom); | ||
897 | } | ||
898 | else | ||
899 | d.GeomSetCollideBits(prim_geom, 0); | ||
900 | } | ||
901 | else | ||
902 | { | ||
903 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | ||
904 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | ||
905 | } | ||
1296 | } | 906 | } |
1297 | 907 | ||
1298 | if (childPrim) | 908 | if (childPrim) |
@@ -1351,11 +961,20 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1351 | myrot.W = _orientation.W; | 961 | myrot.W = _orientation.W; |
1352 | d.BodySetQuaternion(Body, ref myrot); | 962 | d.BodySetQuaternion(Body, ref myrot); |
1353 | d.GeomSetBody(prim_geom, Body); | 963 | d.GeomSetBody(prim_geom, Body); |
964 | |||
1354 | m_collisionCategories |= CollisionCategories.Body; | 965 | m_collisionCategories |= CollisionCategories.Body; |
1355 | m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); | 966 | m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); |
1356 | 967 | ||
1357 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | 968 | if (m_NoColide) |
1358 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | 969 | { |
970 | d.GeomSetCategoryBits(prim_geom, 0); | ||
971 | d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land); | ||
972 | } | ||
973 | else | ||
974 | { | ||
975 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | ||
976 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | ||
977 | } | ||
1359 | 978 | ||
1360 | d.BodySetAutoDisableFlag(Body, true); | 979 | d.BodySetAutoDisableFlag(Body, true); |
1361 | d.BodySetAutoDisableSteps(Body, body_autodisable_frames); | 980 | d.BodySetAutoDisableSteps(Body, body_autodisable_frames); |
@@ -1723,11 +1342,19 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1723 | 1342 | ||
1724 | if (prim_geom != IntPtr.Zero) | 1343 | if (prim_geom != IntPtr.Zero) |
1725 | { | 1344 | { |
1726 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | 1345 | if (m_NoColide) |
1727 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | 1346 | { |
1347 | d.GeomSetCategoryBits(prim_geom, 0); | ||
1348 | d.GeomSetCollideBits(prim_geom, 0); | ||
1349 | d.GeomDisable(prim_geom); | ||
1350 | } | ||
1351 | else | ||
1352 | { | ||
1353 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | ||
1354 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | ||
1355 | } | ||
1728 | } | 1356 | } |
1729 | 1357 | ||
1730 | |||
1731 | d.BodyDestroy(Body); | 1358 | d.BodyDestroy(Body); |
1732 | lock (childrenPrim) | 1359 | lock (childrenPrim) |
1733 | { | 1360 | { |
@@ -1735,6 +1362,13 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1735 | { | 1362 | { |
1736 | foreach (OdePrim prm in childrenPrim) | 1363 | foreach (OdePrim prm in childrenPrim) |
1737 | { | 1364 | { |
1365 | if (prm.m_NoColide && prm.prim_geom != IntPtr.Zero) | ||
1366 | { | ||
1367 | d.GeomSetCategoryBits(prm.prim_geom, 0); | ||
1368 | d.GeomSetCollideBits(prm.prim_geom, 0); | ||
1369 | d.GeomDisable(prm.prim_geom); | ||
1370 | } | ||
1371 | |||
1738 | _parent_scene.remActivePrim(prm); | 1372 | _parent_scene.remActivePrim(prm); |
1739 | prm.Body = IntPtr.Zero; | 1373 | prm.Body = IntPtr.Zero; |
1740 | } | 1374 | } |
@@ -1752,8 +1386,18 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1752 | 1386 | ||
1753 | if (prim_geom != IntPtr.Zero) | 1387 | if (prim_geom != IntPtr.Zero) |
1754 | { | 1388 | { |
1755 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | 1389 | if (m_NoColide) |
1756 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | 1390 | { |
1391 | d.GeomSetCategoryBits(prim_geom, 0); | ||
1392 | d.GeomSetCollideBits(prim_geom, 0); | ||
1393 | d.GeomDisable(prim_geom); | ||
1394 | } | ||
1395 | else | ||
1396 | { | ||
1397 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | ||
1398 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | ||
1399 | } | ||
1400 | |||
1757 | } | 1401 | } |
1758 | 1402 | ||
1759 | 1403 | ||
@@ -1768,11 +1412,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1768 | 1412 | ||
1769 | public bool setMesh(OdeScene parent_scene, IMesh mesh) | 1413 | public bool setMesh(OdeScene parent_scene, IMesh mesh) |
1770 | { | 1414 | { |
1771 | // This sleeper is there to moderate how long it takes between | ||
1772 | // setting up the mesh and pre-processing it when we get rapid fire mesh requests on a single object | ||
1773 | |||
1774 | //Thread.Sleep(10); | ||
1775 | |||
1776 | //Kill Body so that mesh can re-make the geom | 1415 | //Kill Body so that mesh can re-make the geom |
1777 | if (IsPhysical && Body != IntPtr.Zero) | 1416 | if (IsPhysical && Body != IntPtr.Zero) |
1778 | { | 1417 | { |
@@ -1790,14 +1429,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1790 | } | 1429 | } |
1791 | } | 1430 | } |
1792 | 1431 | ||
1793 | // do it on caller instead | ||
1794 | /* | ||
1795 | if (_triMeshData != IntPtr.Zero) | ||
1796 | { | ||
1797 | d.GeomTriMeshDataDestroy(_triMeshData); | ||
1798 | _triMeshData = IntPtr.Zero; | ||
1799 | } | ||
1800 | */ | ||
1801 | IntPtr vertices, indices; | 1432 | IntPtr vertices, indices; |
1802 | int vertexCount, indexCount; | 1433 | int vertexCount, indexCount; |
1803 | int vertexStride, triStride; | 1434 | int vertexStride, triStride; |
@@ -1809,38 +1440,20 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1809 | 1440 | ||
1810 | if (vertexCount == 0 || indexCount == 0) | 1441 | if (vertexCount == 0 || indexCount == 0) |
1811 | { | 1442 | { |
1812 | m_log.WarnFormat("[PHYSICS]: Got invalid mesh on prim {0} at <{1},{2},{3}>. It can be a sculp with alpha channel in map. Replacing it by a small box.", Name, _position.X, _position.Y, _position.Z); | 1443 | m_log.WarnFormat("[PHYSICS]: Got invalid mesh on prim {0} at <{1},{2},{3}>. mesh UUID {4}", Name, _position.X, _position.Y, _position.Z, _pbs.SculptTexture.ToString()); |
1813 | _size.X = 0.05f; | ||
1814 | _size.Y = 0.05f; | ||
1815 | _size.Z = 0.05f; | ||
1816 | return false; | 1444 | return false; |
1817 | } | 1445 | } |
1818 | 1446 | ||
1819 | /* | 1447 | IntPtr geo = IntPtr.Zero; |
1820 | if (m_MeshToTriMeshMap.ContainsKey(mesh)) | 1448 | try |
1821 | { | ||
1822 | _triMeshData = m_MeshToTriMeshMap[mesh]; | ||
1823 | } | ||
1824 | else | ||
1825 | */ | ||
1826 | |||
1827 | |||
1828 | { | 1449 | { |
1829 | _triMeshData = d.GeomTriMeshDataCreate(); | 1450 | _triMeshData = d.GeomTriMeshDataCreate(); |
1830 | |||
1831 | d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride); | 1451 | d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride); |
1832 | d.GeomTriMeshDataPreprocess(_triMeshData); | 1452 | d.GeomTriMeshDataPreprocess(_triMeshData); |
1833 | // m_MeshToTriMeshMap[mesh] = _triMeshData; | ||
1834 | } | ||
1835 | 1453 | ||
1836 | _parent_scene.waitForSpaceUnlock(m_targetSpace); | 1454 | _parent_scene.waitForSpaceUnlock(m_targetSpace); |
1837 | try | 1455 | |
1838 | { | 1456 | geo = d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null); |
1839 | // if (prim_geom == IntPtr.Zero) // setGeom takes care of phys engine recreate and prim_geom pointer | ||
1840 | // { | ||
1841 | // SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, parent_scene.triCallback, null, null)); | ||
1842 | SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null)); | ||
1843 | // } | ||
1844 | } | 1457 | } |
1845 | catch (Exception e) | 1458 | catch (Exception e) |
1846 | { | 1459 | { |
@@ -1851,21 +1464,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1851 | d.GeomTriMeshDataDestroy(_triMeshData); | 1464 | d.GeomTriMeshDataDestroy(_triMeshData); |
1852 | _triMeshData = IntPtr.Zero; | 1465 | _triMeshData = IntPtr.Zero; |
1853 | } | 1466 | } |
1854 | _size.X = 0.05f; | ||
1855 | _size.Y = 0.05f; | ||
1856 | _size.Z = 0.05f; | ||
1857 | return false; | 1467 | return false; |
1858 | } | 1468 | } |
1859 | 1469 | ||
1470 | SetGeom(geo); | ||
1860 | 1471 | ||
1861 | // if (IsPhysical && Body == (IntPtr) 0) | ||
1862 | // { | ||
1863 | // Recreate the body | ||
1864 | // m_interpenetrationcount = 0; | ||
1865 | // m_collisionscore = 0; | ||
1866 | |||
1867 | // enableBody(); | ||
1868 | // } | ||
1869 | return true; | 1472 | return true; |
1870 | } | 1473 | } |
1871 | 1474 | ||
@@ -1943,18 +1546,21 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1943 | if (m_taintvehicledata != null) | 1546 | if (m_taintvehicledata != null) |
1944 | DoSetVehicle(); | 1547 | DoSetVehicle(); |
1945 | 1548 | ||
1946 | if (m_taintserial != null) | ||
1947 | DoSerialize(m_taintserial); | ||
1948 | |||
1949 | /* obsolete | 1549 | /* obsolete |
1950 | if (!m_angularLock.ApproxEquals(m_taintAngularLock,0f)) | 1550 | if (!m_angularLock.ApproxEquals(m_taintAngularLock,0f)) |
1951 | changeAngularLock(timestep); | 1551 | changeAngularLock(timestep); |
1952 | */ | 1552 | */ |
1953 | } | 1553 | } |
1554 | |||
1954 | else | 1555 | else |
1955 | { | 1556 | { |
1956 | m_log.Error("[PHYSICS]: The scene reused a disposed PhysActor! *waves finger*, Don't be evil. A couple of things can cause this. An improper prim breakdown(be sure to set prim_geom to zero after d.GeomDestroy! An improper buildup (creating the geom failed). Or, the Scene Reused a physics actor after disposing it.)"); | 1557 | m_log.Error("[PHYSICS]: prim {0} at <{1},{2},{3}> as invalid geom"); |
1558 | |||
1559 | // not sure this will not flame... | ||
1560 | m_taintremove = true; | ||
1561 | _parent_scene.AddPhysicsActorTaint(this); | ||
1957 | } | 1562 | } |
1563 | |||
1958 | } | 1564 | } |
1959 | 1565 | ||
1960 | /* obsolete | 1566 | /* obsolete |
@@ -2058,7 +1664,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2058 | } | 1664 | } |
2059 | foreach (OdePrim prm in childrenPrim) | 1665 | foreach (OdePrim prm in childrenPrim) |
2060 | { | 1666 | { |
2061 | |||
2062 | prm.m_collisionCategories |= CollisionCategories.Body; | 1667 | prm.m_collisionCategories |= CollisionCategories.Body; |
2063 | prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); | 1668 | prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); |
2064 | 1669 | ||
@@ -2067,9 +1672,17 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2067 | m_log.Warn("[PHYSICS]: Unable to link one of the linkset elements. No geom yet"); | 1672 | m_log.Warn("[PHYSICS]: Unable to link one of the linkset elements. No geom yet"); |
2068 | continue; | 1673 | continue; |
2069 | } | 1674 | } |
2070 | d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories); | ||
2071 | d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags); | ||
2072 | 1675 | ||
1676 | if (prm.m_NoColide) | ||
1677 | { | ||
1678 | d.GeomSetCategoryBits(prm.prim_geom, 0); | ||
1679 | d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land); | ||
1680 | } | ||
1681 | else | ||
1682 | { | ||
1683 | d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories); | ||
1684 | d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags); | ||
1685 | } | ||
2073 | 1686 | ||
2074 | d.Quaternion quat = new d.Quaternion(); | 1687 | d.Quaternion quat = new d.Quaternion(); |
2075 | quat.W = prm._orientation.W; | 1688 | quat.W = prm._orientation.W; |
@@ -2098,20 +1711,28 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2098 | m_log.Debug("[PHYSICS]:I ain't got no boooooooooddy, no body"); | 1711 | m_log.Debug("[PHYSICS]:I ain't got no boooooooooddy, no body"); |
2099 | } | 1712 | } |
2100 | 1713 | ||
2101 | |||
2102 | prm.m_interpenetrationcount = 0; | 1714 | prm.m_interpenetrationcount = 0; |
2103 | prm.m_collisionscore = 0; | 1715 | prm.m_collisionscore = 0; |
2104 | prm.m_disabled = false; | 1716 | prm.m_disabled = false; |
2105 | 1717 | ||
2106 | prm.Body = Body; | 1718 | prm.Body = Body; |
2107 | _parent_scene.addActivePrim(prm); | 1719 | |
1720 | _parent_scene.addActivePrim(prm); | ||
2108 | } | 1721 | } |
1722 | |||
2109 | m_collisionCategories |= CollisionCategories.Body; | 1723 | m_collisionCategories |= CollisionCategories.Body; |
2110 | m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); | 1724 | m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); |
2111 | 1725 | ||
2112 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | 1726 | if (m_NoColide) |
2113 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | 1727 | { |
2114 | 1728 | d.GeomSetCategoryBits(prim_geom, 0); | |
1729 | d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land); | ||
1730 | } | ||
1731 | else | ||
1732 | { | ||
1733 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | ||
1734 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | ||
1735 | } | ||
2115 | 1736 | ||
2116 | d.Quaternion quat2 = new d.Quaternion(); | 1737 | d.Quaternion quat2 = new d.Quaternion(); |
2117 | quat2.W = _orientation.W; | 1738 | quat2.W = _orientation.W; |
@@ -2134,19 +1755,18 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2134 | d.BodySetAutoDisableFlag(Body, true); | 1755 | d.BodySetAutoDisableFlag(Body, true); |
2135 | d.BodySetAutoDisableSteps(Body, body_autodisable_frames); | 1756 | d.BodySetAutoDisableSteps(Body, body_autodisable_frames); |
2136 | 1757 | ||
2137 | |||
2138 | m_interpenetrationcount = 0; | 1758 | m_interpenetrationcount = 0; |
2139 | m_collisionscore = 0; | 1759 | m_collisionscore = 0; |
2140 | m_disabled = false; | 1760 | m_disabled = false; |
2141 | 1761 | ||
2142 | d.BodySetPosition(Body, Position.X, Position.Y, Position.Z); | 1762 | d.BodySetPosition(Body, Position.X, Position.Y, Position.Z); |
2143 | if (m_type != Vehicle.TYPE_NONE) Enable(Body, _parent_scene); | 1763 | if (m_type != Vehicle.TYPE_NONE) Enable(Body, _parent_scene); |
1764 | |||
2144 | _parent_scene.addActivePrim(this); | 1765 | _parent_scene.addActivePrim(this); |
2145 | } | 1766 | } |
2146 | } | 1767 | } |
2147 | } | 1768 | } |
2148 | } | 1769 | } |
2149 | |||
2150 | } | 1770 | } |
2151 | 1771 | ||
2152 | private void ChildSetGeom(OdePrim odePrim) | 1772 | private void ChildSetGeom(OdePrim odePrim) |
@@ -2258,6 +1878,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2258 | { | 1878 | { |
2259 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | 1879 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); |
2260 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | 1880 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); |
1881 | if (m_NoColide) | ||
1882 | d.GeomDisable(prim_geom); | ||
2261 | } | 1883 | } |
2262 | 1884 | ||
2263 | if (m_isphysical) | 1885 | if (m_isphysical) |
@@ -2275,22 +1897,35 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2275 | } | 1897 | } |
2276 | else | 1898 | else |
2277 | { | 1899 | { |
2278 | m_collisionCategories = CollisionCategories.Geom; | 1900 | m_collisionCategories = CollisionCategories.Geom; |
2279 | 1901 | if (m_isphysical) | |
2280 | if (m_isphysical) | 1902 | m_collisionCategories |= CollisionCategories.Body; |
2281 | m_collisionCategories |= CollisionCategories.Body; | ||
2282 | 1903 | ||
2283 | m_collisionFlags = m_default_collisionFlags; | 1904 | m_collisionFlags = m_default_collisionFlags; |
2284 | 1905 | ||
2285 | if (m_collidesLand) | 1906 | if (m_collidesLand) |
2286 | m_collisionFlags |= CollisionCategories.Land; | 1907 | m_collisionFlags |= CollisionCategories.Land; |
2287 | if (m_collidesWater) | 1908 | if (m_collidesWater) |
2288 | m_collisionFlags |= CollisionCategories.Water; | 1909 | m_collisionFlags |= CollisionCategories.Water; |
2289 | 1910 | ||
2290 | if (prim_geom != IntPtr.Zero) | 1911 | if (prim_geom != IntPtr.Zero) |
2291 | { | 1912 | { |
2292 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | 1913 | if (m_NoColide) |
2293 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | 1914 | { |
1915 | d.GeomSetCategoryBits(prim_geom, 0); | ||
1916 | if (m_isphysical) | ||
1917 | d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land); | ||
1918 | else | ||
1919 | { | ||
1920 | d.GeomSetCollideBits(prim_geom, 0); | ||
1921 | d.GeomDisable(prim_geom); | ||
1922 | } | ||
1923 | } | ||
1924 | else | ||
1925 | { | ||
1926 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | ||
1927 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | ||
1928 | } | ||
2294 | } | 1929 | } |
2295 | if (Body != IntPtr.Zero) | 1930 | if (Body != IntPtr.Zero) |
2296 | { | 1931 | { |
@@ -2330,19 +1965,29 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2330 | { | 1965 | { |
2331 | bool gottrimesh = false; | 1966 | bool gottrimesh = false; |
2332 | 1967 | ||
1968 | m_NoColide = false; // assume all will go well | ||
1969 | |||
2333 | if (_triMeshData != IntPtr.Zero) | 1970 | if (_triMeshData != IntPtr.Zero) |
2334 | { | 1971 | { |
2335 | d.GeomTriMeshDataDestroy(_triMeshData); | 1972 | d.GeomTriMeshDataDestroy(_triMeshData); |
2336 | _triMeshData = IntPtr.Zero; | 1973 | _triMeshData = IntPtr.Zero; |
2337 | } | 1974 | } |
2338 | 1975 | ||
2339 | if (_mesh != null) // Special - make mesh | 1976 | if (_mesh != null) |
2340 | { | 1977 | { |
2341 | gottrimesh = setMesh(_parent_scene, _mesh); | 1978 | gottrimesh = setMesh(_parent_scene, _mesh); |
1979 | if (!gottrimesh) | ||
1980 | { | ||
1981 | // getting a mesh failed, | ||
1982 | // lets go on having a basic box or sphere, with prim size but not coliding | ||
1983 | // physical colides with land, non with nothing | ||
1984 | |||
1985 | m_NoColide = true; | ||
1986 | } | ||
2342 | } | 1987 | } |
2343 | 1988 | ||
2344 | if (!gottrimesh) // not a mesh | 1989 | if (!gottrimesh) |
2345 | { | 1990 | { // we will have a basic box or sphere |
2346 | IntPtr geo = IntPtr.Zero; | 1991 | IntPtr geo = IntPtr.Zero; |
2347 | 1992 | ||
2348 | if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1 | 1993 | if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1 |
@@ -2376,14 +2021,17 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2376 | } | 2021 | } |
2377 | } | 2022 | } |
2378 | 2023 | ||
2379 | if (geo == IntPtr.Zero) | 2024 | if (geo == IntPtr.Zero) // if this happens it must be fixed |
2380 | { | 2025 | { |
2026 | // if it does lets stop what we can | ||
2027 | // not sure this will not flame... | ||
2028 | |||
2381 | m_taintremove = true; | 2029 | m_taintremove = true; |
2382 | _parent_scene.AddPhysicsActorTaint(this); | 2030 | _parent_scene.AddPhysicsActorTaint(this); |
2383 | return; | 2031 | return; |
2384 | } | 2032 | } |
2385 | 2033 | ||
2386 | SetGeom(geo); | 2034 | SetGeom(geo); // this processes the m_NoColide |
2387 | } | 2035 | } |
2388 | } | 2036 | } |
2389 | 2037 | ||
@@ -2415,7 +2063,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2415 | } | 2063 | } |
2416 | } | 2064 | } |
2417 | 2065 | ||
2418 | |||
2419 | lock (_parent_scene.OdeLock) | 2066 | lock (_parent_scene.OdeLock) |
2420 | { | 2067 | { |
2421 | CreateGeom(m_targetSpace, _mesh); | 2068 | CreateGeom(m_targetSpace, _mesh); |
@@ -2518,8 +2165,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2518 | m_taintposition = _position; | 2165 | m_taintposition = _position; |
2519 | } | 2166 | } |
2520 | 2167 | ||
2521 | |||
2522 | |||
2523 | public void rotate(float timestep) | 2168 | public void rotate(float timestep) |
2524 | { | 2169 | { |
2525 | d.Quaternion myrot = new d.Quaternion(); | 2170 | d.Quaternion myrot = new d.Quaternion(); |