void ObjectAddHandler(Packet packet, LLAgent agent) { if (!agent.IsVerified) { m_scene.PresenceAlert(this, agent, "You are logged in with an unverified account. Object creation is disabled."); return; } ObjectAddPacket add = (ObjectAddPacket)packet; Vector3 position = Vector3.Zero; Vector3 scale = add.ObjectData.Scale; PCode pcode = (PCode)add.ObjectData.PCode; PrimFlags flags = (PrimFlags)add.ObjectData.AddFlags; bool bypassRaycast = (add.ObjectData.BypassRaycast == 1); //bool rayEndIsIntersection = (add.ObjectData.RayEndIsIntersection == 1); #region Position Calculation if (bypassRaycast) { position = add.ObjectData.RayEnd; } else if (m_physics != null) { Vector3 direction = (add.ObjectData.RayEnd - add.ObjectData.RayStart); direction /= direction.Length(); Ray ray = new Ray(add.ObjectData.RayStart, direction); ISceneEntity collisionObj; float collisionDist; if (m_physics.FullSceneCollisionTest(true, ray, null, out collisionObj, out collisionDist)) { position = ray.GetPoint(collisionDist); } else { m_log.Warn("Full scene collision test for ray " + ray + " failed"); position = agent.ScenePosition + Vector3.UnitZ; } } position.Z += scale.Z * 0.5f; #endregion Position Calculation if (!CanAddPrims(agent, position, 1)) return; #region Foliage Handling // Set all foliage to phantom if (pcode == PCode.Grass || pcode == PCode.Tree || pcode == PCode.NewTree) { flags |= PrimFlags.Phantom; if (pcode != PCode.Grass) { // Resize based on the foliage type Tree tree = (Tree)add.ObjectData.State; switch (tree) { case Tree.Cypress1: case Tree.Cypress2: scale = new Vector3(4f, 4f, 10f); break; default: scale = new Vector3(4f, 4f, 4f); break; } } } #endregion Foliage Handling #region Prim Creation // Create an object Primitive prim = new Primitive(); prim.Flags = PrimFlags.CastShadows | PrimFlags.InventoryEmpty; prim.Flags |= (PrimFlags)add.ObjectData.AddFlags; // TODO: Security check prim.GroupID = add.AgentData.GroupID; prim.ID = UUID.Random(); prim.MediaURL = String.Empty; prim.OwnerID = agent.ID; prim.Position = position; prim.PrimData.Material = (Material)add.ObjectData.Material; prim.PrimData.PathCurve = (PathCurve)add.ObjectData.PathCurve; prim.PrimData.ProfileCurve = (ProfileCurve)add.ObjectData.ProfileCurve; prim.PrimData.PathBegin = Primitive.UnpackBeginCut(add.ObjectData.PathBegin); prim.PrimData.PathEnd = Primitive.UnpackEndCut(add.ObjectData.PathEnd); prim.PrimData.PathScaleX = Primitive.UnpackPathScale(add.ObjectData.PathScaleX); prim.PrimData.PathScaleY = Primitive.UnpackPathScale(add.ObjectData.PathScaleY); prim.PrimData.PathShearX = Primitive.UnpackPathShear((sbyte)add.ObjectData.PathShearX); prim.PrimData.PathShearY = Primitive.UnpackPathShear((sbyte)add.ObjectData.PathShearY); prim.PrimData.PathTwist = Primitive.UnpackPathTwist(add.ObjectData.PathTwist); prim.PrimData.PathTwistBegin = Primitive.UnpackPathTwist(add.ObjectData.PathTwistBegin); prim.PrimData.PathRadiusOffset = Primitive.UnpackPathTwist(add.ObjectData.PathRadiusOffset); prim.PrimData.PathTaperX = Primitive.UnpackPathTaper(add.ObjectData.PathTaperX); prim.PrimData.PathTaperY = Primitive.UnpackPathTaper(add.ObjectData.PathTaperY); prim.PrimData.PathRevolutions = Primitive.UnpackPathRevolutions(add.ObjectData.PathRevolutions); prim.PrimData.PathSkew = Primitive.UnpackPathTwist(add.ObjectData.PathSkew); prim.PrimData.ProfileBegin = Primitive.UnpackBeginCut(add.ObjectData.ProfileBegin); prim.PrimData.ProfileEnd = Primitive.UnpackEndCut(add.ObjectData.ProfileEnd); prim.PrimData.ProfileHollow = Primitive.UnpackProfileHollow(add.ObjectData.ProfileHollow); prim.PrimData.PCode = pcode; prim.Properties = new Primitive.ObjectProperties(); prim.Properties.CreationDate = DateTime.UtcNow; prim.Properties.CreatorID = agent.ID; prim.Properties.Description = String.Empty; prim.Properties.GroupID = add.AgentData.GroupID; prim.Properties.LastOwnerID = agent.ID; prim.Properties.Name = "Object"; prim.Properties.ObjectID = prim.ID; prim.Properties.OwnerID = prim.OwnerID; prim.Properties.Permissions = m_permissions.GetDefaultPermissions(); prim.Properties.SalePrice = 10; prim.Rotation = add.ObjectData.Rotation; prim.Scale = scale; prim.TextColor = Color4.Black; if (pcode == PCode.Prim) { prim.Textures = new Primitive.TextureEntry(PLYWOOD_TEXTURE); } #endregion Prim Creation // Add this prim to the scene ISceneEntity primObj = new LLPrimitive(prim, m_scene, m_primMesher); m_scene.EntityAddOrUpdate(this, primObj, UpdateFlags.FullUpdate, 0); }
void RezObjectHandler(Packet packet, LLAgent agent) { RezObjectPacket rez = (RezObjectPacket)packet; // Find the target position Vector3 position = Vector3.Zero; Vector3 linksetScale = Vector3.Zero; bool bypassRaycast = (rez.RezData.BypassRaycast == 1); //bool rayEndIsIntersection = rez.RezData.RayEndIsIntersection; #region Position Calculation if (bypassRaycast || m_physics == null) { position = rez.RezData.RayEnd; } else { Vector3 direction = (rez.RezData.RayEnd - rez.RezData.RayStart); direction /= direction.Length(); Ray ray = new Ray(rez.RezData.RayStart, direction); ISceneEntity collisionObj; float collisionDist; if (m_physics.FullSceneCollisionTest(true, ray, null, out collisionObj, out collisionDist)) { position = ray.GetPoint(collisionDist); } else { m_log.Warn("Full scene collision test for ray " + ray + " failed"); position = agent.ScenePosition + Vector3.UnitZ; } } position.Z += linksetScale.Z * 0.5f; #endregion Position Calculation InventoryBase invObject; if (m_inventoryClient.TryGetInventory(agent.ID, rez.InventoryData.ItemID, out invObject) & invObject is InventoryItem) { InventoryItem item = (InventoryItem)invObject; Asset asset; if (m_assetClient.TryGetAsset(item.AssetID, item.ContentType, out asset)) { #region Object Deserialization/Rezzing // Deserialize the asset data into a linkset using (MemoryStream stream = new MemoryStream(asset.Data)) { OSDMap linksetMap = OSDParser.DeserializeJson(stream) as OSDMap; if (linksetMap != null) { IList<LLPrimitive> linkset = LLPrimitive.DeserializeLinkset(linksetMap, m_scene, m_primMesher, true); // Rez the parent(s) first for (int i = 0; i < linkset.Count; i++) { LLPrimitive prim = linkset[i]; // Make sure the ownerID is set correctly prim.OwnerID = agent.ID; if (prim.Parent == null) { RezSinglePrim(prim, rez.RezData, position); m_log.Debug("Deserialized root prim " + prim.ID + " (" + prim.LocalID + ") from inventory"); } } // Rez the children for (int i = 0; i < linkset.Count; i++) { if (linkset[i].Parent != null) RezSinglePrim(linkset[i], rez.RezData, position); } // FIXME: Use these to determine if we need to delete the source inventory or task item //rez.RezData.FromTaskID //rez.RezData.RemoveItem } else { m_log.WarnFormat("Failed to deserialize asset {0} ({1} bytes, Content-Type: {2}) into a linkset", asset.ID, asset.Data.Length, asset.ContentType); } } #endregion Object Deserialization/Rezzing } else { m_log.Warn(agent.Name + "'s RezObject failed to retrieve asset " + item.AssetID); } } else { m_log.Warn(agent.Name + " called RezObject for unknown item " + rez.InventoryData.ItemID); } }