GetWorldPosition() public method

Method for a prim to get it's world position from the group. Remember, the Group Position simply gives the position of the group itself
public GetWorldPosition ( ) : System.Vector3
return System.Vector3
        /// <summary>
        /// Delink the given prim from this group.  The delinked prim is established as
        /// an independent SceneObjectGroup.
        /// </summary>
        /// <remarks>
        /// FIXME: This method should not be called directly since it bypasses update locking, allowing a potential race
        /// condition.  But currently there is no
        /// alternative method that does take a lock to delink a single prim.
        /// </remarks>
        /// <param name="partID"></param>
        /// <param name="sendEvents"></param>
        /// <returns>The object group of the newly delinked prim.</returns>
        public SceneObjectGroup DelinkFromGroup(SceneObjectPart linkPart, bool sendEvents)
        {
//                m_log.DebugFormat(
//                    "[SCENE OBJECT GROUP]: Delinking part {0}, {1} from group with root part {2}, {3}",
//                    linkPart.Name, linkPart.UUID, RootPart.Name, RootPart.UUID);
            
            linkPart.ClearUndoState();

            Vector3 worldPos = linkPart.GetWorldPosition();
            Quaternion worldRot = linkPart.GetWorldRotation();

            // Remove the part from this object
            lock (m_parts.SyncRoot)
            {
                m_parts.Remove(linkPart.UUID);

                SceneObjectPart[] parts = m_parts.GetArray();

                // Rejigger the linknum's of the remaining SOP's to fill any gap
                if (parts.Length == 1 && RootPart != null)
                {
                    // Single prim left
                    RootPart.LinkNum = 0;
                }
                else
                {
                    for (int i = 0; i < parts.Length; i++)
                    {
                        SceneObjectPart part = parts[i];
                        if (part.LinkNum > linkPart.LinkNum)
                            part.LinkNum--;
                    }
                }
            }

            linkPart.ParentID = 0;
            linkPart.LinkNum = 0;

            PhysicsActor linkPartPa = linkPart.PhysActor;

            // Remove the SOP from the physical scene.
            // If the new SOG is physical, it is re-created later.
            // (There is a problem here in that we have not yet told the physics
            //    engine about the delink. Someday, linksets should be made first
            //    class objects in the physics engine interface).
            if (linkPartPa != null)
                m_scene.PhysicsScene.RemovePrim(linkPartPa);

            // We need to reset the child part's position
            // ready for life as a separate object after being a part of another object

            /* This commented out code seems to recompute what GetWorldPosition already does.
             * Replace with a call to GetWorldPosition (before unlinking)
            Quaternion parentRot = m_rootPart.RotationOffset;
            Vector3 axPos = linkPart.OffsetPosition;
            axPos *= parentRot;
            linkPart.OffsetPosition = new Vector3(axPos.X, axPos.Y, axPos.Z);
            linkPart.GroupPosition = AbsolutePosition + linkPart.OffsetPosition;
            linkPart.OffsetPosition = new Vector3(0, 0, 0);
             */
            linkPart.GroupPosition = worldPos;
            linkPart.OffsetPosition = Vector3.Zero;
            linkPart.RotationOffset = worldRot;

            // Create a new SOG to go around this unlinked and unattached SOP
            SceneObjectGroup objectGroup = new SceneObjectGroup(linkPart);

            m_scene.AddNewSceneObject(objectGroup, true);

            if (sendEvents)
                linkPart.TriggerScriptChangedEvent(Changed.LINK);

            linkPart.Rezzed = RootPart.Rezzed;

            // When we delete a group, we currently have to force persist to the database if the object id has changed
            // (since delete works by deleting all rows which have a given object id)
            objectGroup.HasGroupChangedDueToDelink = true;

            return objectGroup;
        }
Beispiel #2
0
 // Old uuid and new sceneobjectgroup
 public AuraMetaEntity CreateAuraForNewlyCreatedEntity(SceneObjectPart part)
 {
     AuraMetaEntity ent = new AuraMetaEntity(part.ParentGroup.Scene,
                                             part.GetWorldPosition(),
                                             MetaEntity.TRANSLUCENT,
                                             new Vector3(0,254,0),
                                             part.Scale
                                             );
     m_NewlyCreatedEntityAura.Add(part.UUID, ent);
     return ent;
 }
Beispiel #3
0
        private void CreatePrim(WarpRenderer renderer, SceneObjectPart prim,
                bool useTextures)
        {
            const float MIN_SIZE = 2f;

            if ((PCode)prim.Shape.PCode != PCode.Prim)
                return;
            if (prim.Scale.LengthSquared() < MIN_SIZE * MIN_SIZE)
                return;

            Primitive omvPrim = prim.Shape.ToOmvPrimitive(prim.OffsetPosition, prim.RotationOffset);
            FacetedMesh renderMesh = m_primMesher.GenerateFacetedMesh(omvPrim, DetailLevel.Medium);
            if (renderMesh == null)
                return;

            warp_Vector primPos = ConvertVector(prim.GetWorldPosition());
            warp_Quaternion primRot = ConvertQuaternion(prim.RotationOffset);

            warp_Matrix m = warp_Matrix.quaternionMatrix(primRot);

            if (prim.ParentID != 0)
            {
                SceneObjectGroup group = m_scene.SceneGraph.GetGroupByPrim(prim.LocalId);
                if (group != null)
                    m.transform(warp_Matrix.quaternionMatrix(ConvertQuaternion(group.RootPart.RotationOffset)));
            }

            warp_Vector primScale = ConvertVector(prim.Scale);

            string primID = prim.UUID.ToString();

            // Create the prim faces
            // TODO: Implement the useTextures flag behavior
            for (int i = 0; i < renderMesh.Faces.Count; i++)
            {
                Face face = renderMesh.Faces[i];
                string meshName = primID + "-Face-" + i.ToString();

                // Avoid adding duplicate meshes to the scene
                if (renderer.Scene.objectData.ContainsKey(meshName))
                {
                    continue;
                }

                warp_Object faceObj = new warp_Object(face.Vertices.Count, face.Indices.Count / 3);

                for (int j = 0; j < face.Vertices.Count; j++)
                {
                    Vertex v = face.Vertices[j];

                    warp_Vector pos = ConvertVector(v.Position);
                    warp_Vector norm = ConvertVector(v.Normal);
                    
                    if (prim.Shape.SculptTexture == UUID.Zero)
                        norm = norm.reverse();
                    warp_Vertex vert = new warp_Vertex(pos, norm, v.TexCoord.X, v.TexCoord.Y);

                    faceObj.addVertex(vert);
                }

                for (int j = 0; j < face.Indices.Count; j += 3)
                {
                    faceObj.addTriangle(
                        face.Indices[j + 0],
                        face.Indices[j + 1],
                        face.Indices[j + 2]);
                }

                Primitive.TextureEntryFace teFace = prim.Shape.Textures.GetFace((uint)i);
                Color4 faceColor = GetFaceColor(teFace);
                string materialName = GetOrCreateMaterial(renderer, faceColor);

                faceObj.transform(m);
                faceObj.setPos(primPos);
                faceObj.scaleSelf(primScale.x, primScale.y, primScale.z);

                renderer.Scene.addObject(meshName, faceObj);

                renderer.SetObjectMaterial(meshName, materialName);
            }
        }
        /// <summary>
        /// Delink the given prim from this group.  The delinked prim is established as
        /// an independent SceneObjectGroup.
        /// </summary>
        /// <remarks>
        /// FIXME: This method should not be called directly since it bypasses update locking, allowing a potential race
        /// condition.  But currently there is no
        /// alternative method that does take a lock to delink a single prim.
        /// </remarks>
        /// <param name="partID"></param>
        /// <param name="sendEvents"></param>
        /// <returns>The object group of the newly delinked prim.</returns>
        public SceneObjectGroup DelinkFromGroup(SceneObjectPart linkPart, bool sendEvents)
        {
//                m_log.DebugFormat(
//                    "[SCENE OBJECT GROUP]: Delinking part {0}, {1} from group with root part {2}, {3}",
//                    linkPart.Name, linkPart.UUID, RootPart.Name, RootPart.UUID);
            
            linkPart.ClearUndoState();

            Vector3 worldPos = linkPart.GetWorldPosition();
            Quaternion worldRot = linkPart.GetWorldRotation();

            // Remove the part from this object
            lock (m_parts.SyncRoot)
            {
                m_parts.Remove(linkPart.UUID);

                SceneObjectPart[] parts = m_parts.GetArray();

                // Rejigger the linknum's of the remaining SOP's to fill any gap
                if (parts.Length == 1 && RootPart != null)
                {
                    // Single prim left
                    RootPart.LinkNum = 0;
                }
                else
                {
                    for (int i = 0; i < parts.Length; i++)
                    {
                        SceneObjectPart part = parts[i];
                        if (part.LinkNum > linkPart.LinkNum)
                            part.LinkNum--;
                    }
                }
            }

            linkPart.ParentID = 0;
            linkPart.LinkNum = 0;

            PhysicsActor linkPartPa = linkPart.PhysActor;

            // Remove the SOP from the physical scene.
            // If the new SOG is physical, it is re-created later.
            // (There is a problem here in that we have not yet told the physics
            //    engine about the delink. Someday, linksets should be made first
            //    class objects in the physics engine interface).
            if (linkPartPa != null)
                m_scene.PhysicsScene.RemovePrim(linkPartPa);

            // We need to reset the child part's position
            // ready for life as a separate object after being a part of another object

            /* This commented out code seems to recompute what GetWorldPosition already does.
             * Replace with a call to GetWorldPosition (before unlinking)
            Quaternion parentRot = m_rootPart.RotationOffset;
            Vector3 axPos = linkPart.OffsetPosition;
            axPos *= parentRot;
            linkPart.OffsetPosition = new Vector3(axPos.X, axPos.Y, axPos.Z);
            linkPart.GroupPosition = AbsolutePosition + linkPart.OffsetPosition;
            linkPart.OffsetPosition = new Vector3(0, 0, 0);
             */
            linkPart.GroupPosition = worldPos;
            linkPart.OffsetPosition = Vector3.Zero;
            linkPart.RotationOffset = worldRot;

            // Create a new SOG to go around this unlinked and unattached SOP
            SceneObjectGroup objectGroup = new SceneObjectGroup(linkPart);

            m_scene.AddNewSceneObject(objectGroup, true);

            if (sendEvents)
                linkPart.TriggerScriptChangedEvent(Changed.LINK);

            linkPart.Rezzed = RootPart.Rezzed;

            // We must persist the delinked group to the database immediately, for safety. The problem
            // is that although in memory the new group has a new SceneGroupID, in the database it
            // still has the parent group's SceneGroupID (until the next backup). This means that if the
            // parent group is deleted then the delinked group will also be deleted from the database.
            // This problem will disappear if the region remains alive long enough for another backup,
            // since at that time the delinked group's new SceneGroupID will be written to the database.
            // But if the region crashes before that then the prims will be permanently gone, and this must
            // not happen. (We can't use a just-in-time trick like GroupContainsForeignPrims in this case
            // because the delinked group doesn't know when the source group is deleted.)
            m_scene.ForceSceneObjectBackup(objectGroup);

            return objectGroup;
        }
        private void CreatePrim(WarpRenderer renderer, SceneObjectPart prim,
                bool useTextures)
        {
            const float MIN_SIZE = 2f;

            if ((PCode)prim.Shape.PCode != PCode.Prim)
                return;
            if (prim.Scale.LengthSquared() < MIN_SIZE * MIN_SIZE)
                return;

            FacetedMesh renderMesh = null;
            Primitive omvPrim = prim.Shape.ToOmvPrimitive(prim.OffsetPosition, prim.RotationOffset);

            if (m_renderMeshes)
            {
                if (omvPrim.Sculpt != null && omvPrim.Sculpt.SculptTexture != UUID.Zero)
                {
                    // Try fetchinng the asset
                    byte[] sculptAsset = m_scene.AssetService.GetData(omvPrim.Sculpt.SculptTexture.ToString());
                    if (sculptAsset != null)
                    {
                        // Is it a mesh?
                        if (omvPrim.Sculpt.Type == SculptType.Mesh)
                        {
                            AssetMesh meshAsset = new AssetMesh(omvPrim.Sculpt.SculptTexture, sculptAsset);
                            FacetedMesh.TryDecodeFromAsset(omvPrim, meshAsset, DetailLevel.Highest, out renderMesh);
                            meshAsset = null;
                        }
                        else // It's sculptie
                        {
                            IJ2KDecoder imgDecoder = m_scene.RequestModuleInterface<IJ2KDecoder>();
                            if (imgDecoder != null)
                            {
                                Image sculpt = imgDecoder.DecodeToImage(sculptAsset);
                                if (sculpt != null)
                                {
                                    renderMesh = m_primMesher.GenerateFacetedSculptMesh(omvPrim, (Bitmap)sculpt,
                                                                                        DetailLevel.Medium);
                                    sculpt.Dispose();
                                }
                            }
                        }
                    }
                }
            }

            // If not a mesh or sculptie, try the regular mesher
            if (renderMesh == null)
            {
                renderMesh = m_primMesher.GenerateFacetedMesh(omvPrim, DetailLevel.Medium);
            }

            if (renderMesh == null)
                return;

            warp_Vector primPos = ConvertVector(prim.GetWorldPosition());
            warp_Quaternion primRot = ConvertQuaternion(prim.RotationOffset);

            warp_Matrix m = warp_Matrix.quaternionMatrix(primRot);

            if (prim.ParentID != 0)
            {
                SceneObjectGroup group = m_scene.SceneGraph.GetGroupByPrim(prim.LocalId);
                if (group != null)
                    m.transform(warp_Matrix.quaternionMatrix(ConvertQuaternion(group.RootPart.RotationOffset)));
            }

            warp_Vector primScale = ConvertVector(prim.Scale);

            string primID = prim.UUID.ToString();

            // Create the prim faces
            // TODO: Implement the useTextures flag behavior
            for (int i = 0; i < renderMesh.Faces.Count; i++)
            {
                Face face = renderMesh.Faces[i];
                string meshName = primID + "-Face-" + i.ToString();

                // Avoid adding duplicate meshes to the scene
                if (renderer.Scene.objectData.ContainsKey(meshName))
                {
                    continue;
                }

                warp_Object faceObj = new warp_Object(face.Vertices.Count, face.Indices.Count / 3);

                for (int j = 0; j < face.Vertices.Count; j++)
                {
                    Vertex v = face.Vertices[j];

                    warp_Vector pos = ConvertVector(v.Position);
                    warp_Vector norm = ConvertVector(v.Normal);
                    
                    if (prim.Shape.SculptTexture == UUID.Zero)
                        norm = norm.reverse();
                    warp_Vertex vert = new warp_Vertex(pos, norm, v.TexCoord.X, v.TexCoord.Y);

                    faceObj.addVertex(vert);
                }

                for (int j = 0; j < face.Indices.Count; j += 3)
                {
                    faceObj.addTriangle(
                        face.Indices[j + 0],
                        face.Indices[j + 1],
                        face.Indices[j + 2]);
                }

                Primitive.TextureEntryFace teFace = prim.Shape.Textures.GetFace((uint)i);
                Color4 faceColor = GetFaceColor(teFace);
                string materialName = String.Empty;
                if (m_texturePrims && prim.Scale.LengthSquared() > m_texturePrimSize*m_texturePrimSize)
                    materialName = GetOrCreateMaterial(renderer, faceColor, teFace.TextureID);
                else
                    materialName = GetOrCreateMaterial(renderer, faceColor);

                faceObj.transform(m);
                faceObj.setPos(primPos);
                faceObj.scaleSelf(primScale.x, primScale.y, primScale.z);

                renderer.Scene.addObject(meshName, faceObj);

                renderer.SetObjectMaterial(meshName, materialName);
            }
        }