public void botSetMap(string keyOfBot, LSL_List positions, LSL_List movementType, LSL_Integer flags) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.Moderate, "botSetMap", m_host, "bot", m_itemID)) { return; } List <Vector3> PositionsMap = new List <Vector3>(); for (int i = 0; i < positions.Length; i++) { LSL_Vector pos = positions.GetVector3Item(i); PositionsMap.Add(new Vector3((float)pos.x, (float)pos.y, (float)pos.z)); } List <TravelMode> TravelMap = new List <TravelMode>(); for (int i = 0; i < movementType.Length; i++) { LSL_Integer travel = movementType.GetLSLIntegerItem(i); TravelMap.Add((TravelMode)travel.value); } IBotManager manager = World.RequestModuleInterface <IBotManager>(); if (manager != null) { manager.SetBotMap(UUID.Parse(keyOfBot), PositionsMap, TravelMap, flags.value, m_host.OwnerID); } }
public LSL_List llGetStaticPath(LSL_Vector start, LSL_Vector end, LSL_Float radius, LSL_List parameters) { NotImplemented("llGetStaticPath", "Not implemented at this moment"); LSL_List empty = new LSL_List(); return(empty); }
public LSL_List llGetClosestNavPoint(LSL_Vector point, LSL_List options) { Vector3 diff = new Vector3(0, 0, 0.1f) * (Vector3.RotationBetween(m_host.ParentEntity.AbsolutePosition, point.ToVector3())); return(new LSL_List(new LSL_Vector((m_host.ParentEntity.AbsolutePosition + diff)))); }
public LSL_Vector llVecNorm(LSL_Vector v) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return(new LSL_Vector()); } return(LSL_Vector.Norm(v)); }
public void llSitTarget(LSL_Vector offset, LSL_Rotation rot) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return; } SitTarget(m_host, offset, rot); }
//This next group are vector operations involving squaring and square root. ckrinke public LSL_Float llVecMag(LSL_Vector v) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return(new LSL_Float()); } return(LSL_Vector.Mag(v)); }
public void llMoveToTarget(LSL_Vector target, double tau) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return; } m_host.MoveToTarget(new Vector3((float)target.x, (float)target.y, (float)target.z), (float)tau); }
public void llSetScale(LSL_Vector scale) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return; } SetScale(m_host, scale); }
public void llSetColor(LSL_Vector color, int face) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return; } m_host.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); }
public void llSetCameraAtOffset(LSL_Vector offset) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return; } m_host.CameraAtOffset = new Vector3((float)offset.x, (float)offset.y, (float)offset.z); }
public void llApplyRotationalImpulse(LSL_Vector force, int local) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return; } m_host.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0); }
public void llLookAt(LSL_Vector target, double strength, double damping) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return; } LookAt(target, strength, damping, m_host); }
public LSL_Float llWater(LSL_Vector offset) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return(new LSL_Float()); } return(World.RegionInfo.RegionSettings.WaterHeight); }
public void llSetTorque(LSL_Vector torque, int local) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return; } m_host.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0); }
public LSL_Integer llTarget(LSL_Vector position, LSL_Float range) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return(0); } return(m_host.registerTargetWaypoint( new Vector3((float)position.x, (float)position.y, (float)position.z), (float)range)); }
public void llSetForceAndTorque(LSL_Vector force, LSL_Vector torque, int local) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return; } llSetForce(force, local); llSetTorque(torque, local); }
public DateTime llMakeSmoke(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return(DateTime.Now); } Deprecated("llMakeSmoke", "Use llParticleSystem instead"); return(PScriptSleep(m_sleepMsOnMakeSmoke)); }
public LSL_Vector llGroundContour(LSL_Vector offset) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return(new LSL_Vector()); } LSL_Vector x = llGroundSlope(offset); return(new LSL_Vector(-x.y, x.x, 0.0)); }
public LSL_Rotation llAxes2Rot(LSL_Vector fwd, LSL_Vector left, LSL_Vector up) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return(new LSL_Rotation()); } double s; double tr = fwd.x + left.y + up.z + 1.0; if (tr >= 1.0) { s = 0.5 / Math.Sqrt(tr); return(new LSL_Rotation( (left.z - up.y) * s, (up.x - fwd.z) * s, (fwd.y - left.x) * s, 0.25 / s)); } double max = (left.y > up.z) ? left.y : up.z; if (max < fwd.x) { s = Math.Sqrt(fwd.x - (left.y + up.z) + 1.0); double x = s * 0.5; s = 0.5 / s; return(new LSL_Rotation( x, (fwd.y + left.x) * s, (up.x + fwd.z) * s, (left.z - up.y) * s)); } if (FloatAlmostEqual(max, left.y)) { s = Math.Sqrt(left.y - (up.z + fwd.x) + 1.0); double y = s * 0.5; s = 0.5 / s; return(new LSL_Rotation( (fwd.y + left.x) * s, y, (left.z + up.y) * s, (up.x - fwd.z) * s)); } s = Math.Sqrt(up.z - (fwd.x + left.y) + 1.0); double z = s * 0.5; s = 0.5 / s; return(new LSL_Rotation( (up.x + fwd.z) * s, (left.z + up.y) * s, z, (fwd.y - left.x) * s)); }
public DateTime llSetPos(LSL_Vector pos) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return(DateTime.Now); } SetPos(m_host, pos, true); return(PScriptSleep(m_sleepMsOnSetPos)); }
public LSL_Integer llSetRegionPos(LSL_Vector pos) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return(ScriptBaseClass.FALSE); } SetPos(m_host, pos, false); return(ScriptBaseClass.TRUE); }
public LSL_Float llVecDist(LSL_Vector a, LSL_Vector b) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return(new LSL_Float()); } double dx = a.x - b.x; double dy = a.y - b.y; double dz = a.z - b.z; return(Math.Sqrt(dx * dx + dy * dy + dz * dz)); }
public LSL_String botCreateBot(string firstName, string lastName, string appearanceToClone, LSL_Vector startPos) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.Moderate, "botCreateBot", m_host, "bot", m_itemID)) return ""; IBotManager manager = World.RequestModuleInterface<IBotManager>(); if (manager != null) return new LSL_String( manager.CreateAvatar(firstName, lastName, m_host.ParentEntity.Scene, UUID.Parse(appearanceToClone), m_host.OwnerID, new Vector3((float) startPos.x, (float) startPos.y, (float) startPos.z)). ToString()); return new LSL_String(""); }
public void llSetLinkColor(int linknumber, LSL_Vector color, int face) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return; } List <ISceneChildEntity> parts = GetLinkParts(linknumber); foreach (ISceneChildEntity part in parts) { part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); } }
// 04122016 Fly-Man- // This function is unknown on the SL Wiki public void llLinkLookAt(LSL_Integer link, LSL_Vector target, double strength, double damping) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return; } List <ISceneChildEntity> parts = GetLinkParts(link); foreach (ISceneChildEntity part in parts) { LookAt(target, strength, damping, part); } }
public void llTriggerSoundLimited(string sound, double volume, LSL_Vector top_north_east, LSL_Vector bottom_south_west) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return; } double radius1 = (float)llVecDist(llGetPos(), top_north_east); double radius2 = (float)llVecDist(llGetPos(), bottom_south_west); double radius = Math.Abs(radius1 - radius2); m_host.SendSound(KeyOrName(sound, AssetType.Sound, true).ToString(), volume, true, 0, (float)radius); }
public void llSetText(string text, LSL_Vector color, LSL_Float alpha) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return; } Vector3 av3 = new Vector3(Util.Clip((float)color.x, 0.0f, 1.0f), Util.Clip((float)color.y, 0.0f, 1.0f), Util.Clip((float)color.z, 0.0f, 1.0f)); m_host.SetText(text.Length > 254 ? text.Remove(254) : text, av3, Util.Clip((float)alpha, 0.0f, 1.0f)); //m_host.ParentGroup.HasGroupChanged = true; //m_host.ParentGroup.ScheduleGroupForFul; }
public void llSetLinkCamera(LSL_Integer link, LSL_Vector eye, LSL_Vector at) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return; } List <ISceneChildEntity> entities = GetLinkParts(link); if (entities.Count > 0) { entities[0].CameraEyeOffset = new Vector3((float)eye.x, (float)eye.y, (float)eye.z); entities[0].CameraAtOffset = new Vector3((float)at.x, (float)at.y, (float)at.z); } }
public LSL_Integer llScriptDanger(LSL_Vector pos) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return(0); } bool result = m_ScriptEngine.PipeEventsForScript(m_host, new Vector3((float)pos.x, (float)pos.y, (float)pos.z)); if (result) { return(1); } return(0); }
/* The new / changed functions were tested with the following LSL script: * * default * { * state_entry() * { * rotation rot = llEuler2Rot(<0,70,0> * DEG_TO_RAD); * * llOwnerSay("to get here, we rotate over: "+ (string) llRot2Axis(rot)); * llOwnerSay("and we rotate for: "+ (llRot2Angle(rot) * RAD_TO_DEG)); * * // convert back and forth between quaternion <-> vector and angle * * rotation newrot = llAxisAngle2Rot(llRot2Axis(rot),llRot2Angle(rot)); * * llOwnerSay("Old rotation was: "+(string) rot); * llOwnerSay("re-converted rotation is: "+(string) newrot); * * llSetRot(rot); // to check the parameters in the prim * } * } */ // Xantor 29/apr/2008 // Returns rotation described by rotating angle radians about axis. // q = cos(a/2) + i (x * sin(a/2)) + j (y * sin(a/2)) + k (z * sin(a/2)) public LSL_Rotation llAxisAngle2Rot(LSL_Vector axis, LSL_Float angle) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return(new LSL_Rotation()); } double s = Math.Cos(angle * 0.5); double t = Math.Sin(angle * 0.5); double x = axis.x * t; double y = axis.y * t; double z = axis.z * t; return(new LSL_Rotation(x, y, z, s)); }
public void llSetVehicleVectorParam(int param, LSL_Vector vec) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return; } if (m_host.ParentEntity != null) { if (!m_host.ParentEntity.IsDeleted) { m_host.ParentEntity.RootChild.SetVehicleVectorParam(param, new Vector3((float)vec.x, (float)vec.y, (float)vec.z)); } } }
public LSL_Vector llGroundNormal(LSL_Vector offset) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return new LSL_Vector(); Vector3 pos = m_host.GetWorldPosition() + new Vector3((float)offset.x, (float)offset.y, (float)offset.z); ITerrainChannel heightmap = World.RequestModuleInterface<ITerrainChannel>(); // Clamp to valid position if (pos.X < 0) pos.X = 0; else if (pos.X >= heightmap.Width) pos.X = heightmap.Width - 1; if (pos.Y < 0) pos.Y = 0; else if (pos.Y >= heightmap.Height) pos.Y = heightmap.Height - 1; //Find two points in addition to the position to define a plane Vector3 p0 = new Vector3(pos.X, pos.Y, heightmap[(int)pos.X, (int)pos.Y]); Vector3 p1 = new Vector3(); Vector3 p2 = new Vector3(); if ((pos.X + 1.0f) >= heightmap.Width) p1 = new Vector3(pos.X + 1.0f, pos.Y, heightmap[(int)pos.X, (int)pos.Y]); else p1 = new Vector3(pos.X + 1.0f, pos.Y, heightmap[(int)(pos.X + 1.0f), (int)pos.Y]); if ((pos.Y + 1.0f) >= heightmap.Height) p2 = new Vector3(pos.X, pos.Y + 1.0f, heightmap[(int)pos.X, (int)pos.Y]); else p2 = new Vector3(pos.X, pos.Y + 1.0f, heightmap[(int)pos.X, (int)(pos.Y + 1.0f)]); //Find normalized vectors from p0 to p1 and p0 to p2 Vector3 v0 = new Vector3(p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z); Vector3 v1 = new Vector3(p2.X - p0.X, p2.Y - p0.Y, p2.Z - p0.Z); // v0.Normalize(); // v1.Normalize(); //Find the cross product of the vectors (the slope normal). Vector3 vsn = new Vector3 { X = (v0.Y * v1.Z) - (v0.Z * v1.Y), Y = (v0.Z * v1.X) - (v0.X * v1.Z), Z = (v0.X * v1.Y) - (v0.Y * v1.X) }; vsn.Normalize(); //I believe the crossproduct of two normalized vectors is a normalized vector so //this normalization may be overkill // then don't normalize them just the result return new LSL_Vector(vsn.X, vsn.Y, vsn.Z); }
private void SetParticleSystem(ISceneChildEntity part, LSL_List rules) { if (rules.Length == 0) { part.RemoveParticleSystem(); } else { Primitive.ParticleSystem prules = getNewParticleSystemWithSLDefaultValues(); LSL_Vector tempv = new LSL_Vector(); float tempf = 0; int tmpi = 0; for (int i = 0; i < rules.Length; i += 2) { LSL_Integer rule = rules.GetLSLIntegerItem(i); if (rule == (int)ScriptBaseClass.PSYS_PART_FLAGS) { prules.PartDataFlags = (Primitive.ParticleSystem.ParticleDataFlags)(uint)rules.GetLSLIntegerItem(i + 1); } else if (rule == (int)ScriptBaseClass.PSYS_PART_START_COLOR) { tempv = rules.GetVector3Item(i + 1); prules.PartStartColor.R = (float)tempv.x; prules.PartStartColor.G = (float)tempv.y; prules.PartStartColor.B = (float)tempv.z; } else if (rule == (int)ScriptBaseClass.PSYS_PART_START_ALPHA) { tempf = (float)rules.GetLSLFloatItem(i + 1); prules.PartStartColor.A = tempf; } else if (rule == (int)ScriptBaseClass.PSYS_PART_END_COLOR) { tempv = rules.GetVector3Item(i + 1); prules.PartEndColor.R = (float)tempv.x; prules.PartEndColor.G = (float)tempv.y; prules.PartEndColor.B = (float)tempv.z; } else if (rule == (int)ScriptBaseClass.PSYS_PART_END_ALPHA) { tempf = (float)rules.GetLSLFloatItem(i + 1); prules.PartEndColor.A = tempf; } else if (rule == (int)ScriptBaseClass.PSYS_PART_START_SCALE) { tempv = rules.GetVector3Item(i + 1); prules.PartStartScaleX = (float)tempv.x; prules.PartStartScaleY = (float)tempv.y; } else if (rule == (int)ScriptBaseClass.PSYS_PART_END_SCALE) { tempv = rules.GetVector3Item(i + 1); prules.PartEndScaleX = (float)tempv.x; prules.PartEndScaleY = (float)tempv.y; } else if (rule == (int)ScriptBaseClass.PSYS_PART_MAX_AGE) { tempf = (float)rules.GetLSLFloatItem(i + 1); prules.PartMaxAge = tempf; } else if (rule == (int)ScriptBaseClass.PSYS_SRC_ACCEL) { tempv = rules.GetVector3Item(i + 1); prules.PartAcceleration.X = (float)tempv.x; prules.PartAcceleration.Y = (float)tempv.y; prules.PartAcceleration.Z = (float)tempv.z; } else if (rule == (int)ScriptBaseClass.PSYS_SRC_PATTERN) { tmpi = rules.GetLSLIntegerItem(i + 1); prules.Pattern = (Primitive.ParticleSystem.SourcePattern)tmpi; } // PSYS_SRC_INNERANGLE and PSYS_SRC_ANGLE_BEGIN use the same variables. The // PSYS_SRC_OUTERANGLE and PSYS_SRC_ANGLE_END also use the same variable. The // client tells the difference between the two by looking at the 0x02 bit in // the PartFlags variable. else if (rule == (int)ScriptBaseClass.PSYS_SRC_INNERANGLE) { tempf = (float)rules.GetLSLFloatItem(i + 1); prules.InnerAngle = tempf; prules.PartFlags &= 0xFFFFFFFD; // Make sure new angle format is off. } else if (rule == (int)ScriptBaseClass.PSYS_SRC_OUTERANGLE) { tempf = (float)rules.GetLSLFloatItem(i + 1); prules.OuterAngle = tempf; prules.PartFlags &= 0xFFFFFFFD; // Make sure new angle format is off. } else if (rule == (int)ScriptBaseClass.PSYS_PART_BLEND_FUNC_SOURCE) { tmpi = rules.GetLSLIntegerItem(i + 1); prules.BlendFuncSource = (byte)tmpi; } else if (rule == (int)ScriptBaseClass.PSYS_PART_BLEND_FUNC_DEST) { tmpi = rules.GetLSLIntegerItem(i + 1); prules.BlendFuncDest = (byte)tmpi; } else if (rule == (int)ScriptBaseClass.PSYS_PART_START_GLOW) { tempf = (float)rules.GetLSLFloatItem(i + 1); prules.PartStartGlow = tempf; } else if (rule == (int)ScriptBaseClass.PSYS_PART_END_GLOW) { tempf = (float)rules.GetLSLFloatItem(i + 1); prules.PartEndGlow = tempf; } else if (rule == (int)ScriptBaseClass.PSYS_SRC_TEXTURE) { prules.Texture = KeyOrName(rules.GetLSLStringItem(i + 1), AssetType.Texture, false); } else if (rule == (int)ScriptBaseClass.PSYS_SRC_BURST_RATE) { tempf = (float)rules.GetLSLFloatItem(i + 1); prules.BurstRate = tempf; } else if (rule == (int)ScriptBaseClass.PSYS_SRC_BURST_PART_COUNT) { prules.BurstPartCount = (byte)(int)rules.GetLSLIntegerItem(i + 1); } else if (rule == (int)ScriptBaseClass.PSYS_SRC_BURST_RADIUS) { tempf = (float)rules.GetLSLFloatItem(i + 1); prules.BurstRadius = tempf; } else if (rule == (int)ScriptBaseClass.PSYS_SRC_BURST_SPEED_MIN) { tempf = (float)rules.GetLSLFloatItem(i + 1); prules.BurstSpeedMin = tempf; } else if (rule == (int)ScriptBaseClass.PSYS_SRC_BURST_SPEED_MAX) { tempf = (float)rules.GetLSLFloatItem(i + 1); prules.BurstSpeedMax = tempf; } else if (rule == (int)ScriptBaseClass.PSYS_SRC_MAX_AGE) { tempf = (float)rules.GetLSLFloatItem(i + 1); prules.MaxAge = tempf; } else if (rule == (int)ScriptBaseClass.PSYS_SRC_TARGET_KEY) { UUID key = UUID.Zero; prules.Target = UUID.TryParse(rules.Data[i + 1].ToString(), out key) ? key : part.UUID; } else if (rule == (int)ScriptBaseClass.PSYS_SRC_OMEGA) { // AL: This is an assumption, since it is the only thing that would match. tempv = rules.GetVector3Item(i + 1); prules.AngularVelocity.X = (float)tempv.x; prules.AngularVelocity.Y = (float)tempv.y; prules.AngularVelocity.Z = (float)tempv.z; } else if (rule == (int)ScriptBaseClass.PSYS_SRC_ANGLE_BEGIN) { tempf = (float)rules.GetLSLFloatItem(i + 1); prules.InnerAngle = tempf; prules.PartFlags |= 0x02; // Set new angle format. } else if (rule == (int)ScriptBaseClass.PSYS_SRC_ANGLE_END) { tempf = (float)rules.GetLSLFloatItem(i + 1); prules.OuterAngle = tempf; prules.PartFlags |= 0x02; // Set new angle format. } } prules.CRC = 1; part.AddNewParticleSystem(prules); } part.ScheduleUpdate(PrimUpdateFlags.Particles); }
/* The new / changed functions were tested with the following LSL script: default { state_entry() { rotation rot = llEuler2Rot(<0,70,0> * DEG_TO_RAD); llOwnerSay("to get here, we rotate over: "+ (string) llRot2Axis(rot)); llOwnerSay("and we rotate for: "+ (llRot2Angle(rot) * RAD_TO_DEG)); // convert back and forth between quaternion <-> vector and angle rotation newrot = llAxisAngle2Rot(llRot2Axis(rot),llRot2Angle(rot)); llOwnerSay("Old rotation was: "+(string) rot); llOwnerSay("re-converted rotation is: "+(string) newrot); llSetRot(rot); // to check the parameters in the prim } } */ // Xantor 29/apr/2008 // Returns rotation described by rotating angle radians about axis. // q = cos(a/2) + i (x * sin(a/2)) + j (y * sin(a/2)) + k (z * sin(a/2)) public LSL_Rotation llAxisAngle2Rot(LSL_Vector axis, LSL_Float angle) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return new LSL_Rotation(); double s = Math.Cos(angle * 0.5); double t = Math.Sin(angle * 0.5); double x = axis.x * t; double y = axis.y * t; double z = axis.z * t; return new LSL_Rotation(x, y, z, s); }
protected void SitTarget (ISceneChildEntity part, LSL_Vector offset, LSL_Rotation rot) { // LSL quaternions can normalize to 0, normal Quaternions can't. if (FloatAlmostEqual (rot.s, 0) && FloatAlmostEqual (rot.x, 0) && FloatAlmostEqual (rot.y, 0) && FloatAlmostEqual (rot.z, 0)) rot.z = 1; // ZERO_ROTATION = 0,0,0,1 part.SitTargetPosition = new Vector3 ((float)offset.x, (float)offset.y, (float)offset.z);; part.SitTargetOrientation = Rot2Quaternion (rot);; part.ParentEntity.HasGroupChanged = true; }
public void llLinkSitTarget(LSL_Integer link, LSL_Vector offset, LSL_Rotation rot) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return; if (link == ScriptBaseClass.LINK_ROOT) SitTarget (m_host.ParentEntity.RootChild, offset, rot); else if (link == ScriptBaseClass.LINK_THIS) SitTarget (m_host, offset, rot); else { var entity = m_host.ParentEntity.GetLinkNumPart (link); if (entity != null) { SitTarget ((ISceneChildEntity) entity, offset, rot); } } }
protected LSL_Vector GetTextureOffset(ISceneChildEntity part, int face) { Primitive.TextureEntry tex = part.Shape.Textures; LSL_Vector offset = new LSL_Vector(); if (face == ScriptBaseClass.ALL_SIDES) { face = 0; } if (face >= 0 && face < GetNumberOfSides(part)) { offset.x = tex.GetFace((uint)face).OffsetU; offset.y = tex.GetFace((uint)face).OffsetV; offset.z = 0.0; return offset; } return offset; }
public void llTriggerSoundLimited(string sound, double volume, LSL_Vector top_north_east, LSL_Vector bottom_south_west) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return; double radius1 = (float)llVecDist(llGetPos(), top_north_east); double radius2 = (float)llVecDist(llGetPos(), bottom_south_west); double radius = Math.Abs(radius1 - radius2); m_host.SendSound(KeyOrName(sound, AssetType.Sound, true).ToString(), volume, true, 0, (float)radius); }
public LSL_List GetLinkPrimitiveParams(ISceneChildEntity part, LSL_List rules, bool allowOpenSimParams) { LSL_List res = new LSL_List(); int idx = 0; while (idx < rules.Length) { int code = rules.GetLSLIntegerItem(idx++); int remain = rules.Length - idx; Primitive.TextureEntry tex = part.Shape.Textures; int face = 0; if (code == (int)ScriptBaseClass.PRIM_NAME) { res.Add(new LSL_String(part.Name)); } else if (code == (int)ScriptBaseClass.PRIM_DESC) { res.Add(new LSL_String(part.Description)); } else if (code == (int)ScriptBaseClass.PRIM_MATERIAL) { res.Add(new LSL_Integer(part.Material)); } else if (code == (int)ScriptBaseClass.PRIM_PHYSICS) { res.Add((part.GetEffectiveObjectFlags() & (uint)PrimFlags.Physics) != 0 ? new LSL_Integer(1) : new LSL_Integer(0)); } else if (code == (int)ScriptBaseClass.PRIM_TEMP_ON_REZ) { res.Add((part.GetEffectiveObjectFlags() & (uint)PrimFlags.TemporaryOnRez) != 0 ? new LSL_Integer(1) : new LSL_Integer(0)); } else if (code == (int)ScriptBaseClass.PRIM_PHANTOM) { res.Add((part.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) != 0 ? new LSL_Integer(1) : new LSL_Integer(0)); } else if (code == (int)ScriptBaseClass.PRIM_POSITION) { Vector3 tmp = part.AbsolutePosition; LSL_Vector v = new LSL_Vector(tmp.X, tmp.Y, tmp.Z); // For some reason, the part.AbsolutePosition.* values do not change if the // linkset is rotated; they always reflect the child prim's world position // as though the linkset is unrotated. This is incompatible behavior with SL's // implementation, so will break scripts imported from there (not to mention it // makes it more difficult to determine a child prim's actual inworld position). if (part.ParentID != 0) { LSL_Rotation rtmp = llGetRootRotation(); LSL_Vector rpos = llGetRootPosition(); v = ((v - rpos) * rtmp) + rpos; } res.Add(v); } else if (code == (int)ScriptBaseClass.PRIM_POS_LOCAL) { res.Add(GetLocalPos(part)); } else if (code == (int)ScriptBaseClass.PRIM_SIZE) { Vector3 tmp = part.Scale; res.Add(new LSL_Vector(tmp.X, tmp.Y, tmp.Z)); } else if (code == (int)ScriptBaseClass.PRIM_ROTATION) { res.Add(GetPartRot(part)); } else if (code == (int)ScriptBaseClass.PRIM_TYPE) { // implementing box PrimitiveBaseShape Shape = part.Shape; int primType = (int)part.GetPrimType(); res.Add(new LSL_Integer(primType)); double topshearx = (sbyte)Shape.PathShearX / 100.0; // Fix negative values for PathShearX double topsheary = (sbyte)Shape.PathShearY / 100.0; // and PathShearY. if (primType == ScriptBaseClass.PRIM_TYPE_BOX || primType == ScriptBaseClass.PRIM_TYPE_CYLINDER || primType == ScriptBaseClass.PRIM_TYPE_PRISM) { res.Add(new LSL_Integer(Shape.ProfileCurve)); res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0)); res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0)); res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0)); res.Add(new LSL_Vector(1 - (Shape.PathScaleX / 100.0 - 1), 1 - (Shape.PathScaleY / 100.0 - 1), 0)); res.Add(new LSL_Vector(topshearx, topsheary, 0)); } if (primType == ScriptBaseClass.PRIM_TYPE_SPHERE) { res.Add(new LSL_Integer(Shape.ProfileCurve)); res.Add(new LSL_Vector(Shape.PathBegin / 50000.0, 1 - Shape.PathEnd / 50000.0, 0)); res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0)); res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0)); res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0)); } if (primType == ScriptBaseClass.PRIM_TYPE_SCULPT) { res.Add(Shape.SculptTexture.ToString()); res.Add(new LSL_Integer(Shape.SculptType)); } if (primType == ScriptBaseClass.PRIM_TYPE_RING || primType == ScriptBaseClass.PRIM_TYPE_TUBE || primType == ScriptBaseClass.PRIM_TYPE_TORUS) { // holeshape res.Add(new LSL_Integer(Shape.ProfileCurve)); // cut res.Add(new LSL_Vector(Shape.PathBegin / 50000.0, 1 - Shape.PathEnd / 50000.0, 0)); // hollow res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0)); // twist res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0)); // vector holesize res.Add(new LSL_Vector(1 - (Shape.PathScaleX / 100.0 - 1), 1 - (Shape.PathScaleY / 100.0 - 1), 0)); // vector topshear res.Add(new LSL_Vector(topshearx, topsheary, 0)); // vector profilecut res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0)); // vector tapera res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0)); // float revolutions res.Add( new LSL_Float(Math.Round(Shape.PathRevolutions * 0.015d, 2, MidpointRounding.AwayFromZero)) + 1.0d); // Slightly inaccurate, because an unsigned byte is being used to represent // the entire range of floating-point values from 1.0 through 4.0 (which is how // SL does it). // // Using these formulas to store and retrieve PathRevolutions, it is not // possible to use all values between 1.00 and 4.00. For instance, you can't // represent 1.10. You can represent 1.09 and 1.11, but not 1.10. So, if you // use llSetPrimitiveParams to set revolutions to 1.10 and then retreive them // with llGetPrimitiveParams, you'll retrieve 1.09. You can also see a similar // behavior in the viewer as you cannot set 1.10. The viewer jumps to 1.11. // In SL, llSetPrimitveParams and llGetPrimitiveParams can set and get a value // such as 1.10. So, SL must store and retreive the actual user input rather // than only storing the encoded value. // float radiusoffset res.Add(new LSL_Float(Shape.PathRadiusOffset / 100.0)); // float skew res.Add(new LSL_Float(Shape.PathSkew / 100.0)); } } else if (code == (int)ScriptBaseClass.PRIM_TEXTURE) { if (remain < 1) return res; face = rules.GetLSLIntegerItem(idx++); if (face == ScriptBaseClass.ALL_SIDES) { for (face = 0; face < GetNumberOfSides(part); face++) { Primitive.TextureEntryFace texface = tex.GetFace((uint)face); res.Add(new LSL_String(texface.TextureID.ToString())); res.Add(new LSL_Vector(texface.RepeatU, texface.RepeatV, 0)); res.Add(new LSL_Vector(texface.OffsetU, texface.OffsetV, 0)); res.Add(new LSL_Float(texface.Rotation)); } } else { if (face >= 0 && face < GetNumberOfSides(part)) { Primitive.TextureEntryFace texface = tex.GetFace((uint)face); res.Add(new LSL_String(texface.TextureID.ToString())); res.Add(new LSL_Vector(texface.RepeatU, texface.RepeatV, 0)); res.Add(new LSL_Vector(texface.OffsetU, texface.OffsetV, 0)); res.Add(new LSL_Float(texface.Rotation)); } } } else if (code == (int)ScriptBaseClass.PRIM_COLOR) { if (remain < 1) return res; face = rules.GetLSLIntegerItem(idx++); tex = part.Shape.Textures; Color4 texcolor; if (face == ScriptBaseClass.ALL_SIDES) { for (face = 0; face < GetNumberOfSides(part); face++) { texcolor = tex.GetFace((uint)face).RGBA; res.Add(new LSL_Vector(texcolor.R, texcolor.G, texcolor.B)); res.Add(new LSL_Float(texcolor.A)); } } else { texcolor = tex.GetFace((uint)face).RGBA; res.Add(new LSL_Vector(texcolor.R, texcolor.G, texcolor.B)); res.Add(new LSL_Float(texcolor.A)); } } else if (code == (int)ScriptBaseClass.PRIM_BUMP_SHINY) { if (remain < 1) return res; face = rules.GetLSLIntegerItem(idx++); if (face == ScriptBaseClass.ALL_SIDES) { for (face = 0; face < GetNumberOfSides(part); face++) { Primitive.TextureEntryFace texface = tex.GetFace((uint)face); // Convert Shininess to PRIM_SHINY_* res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); // PRIM_BUMP_* res.Add(new LSL_Integer((int)texface.Bump)); } } else { if (face >= 0 && face < GetNumberOfSides(part)) { Primitive.TextureEntryFace texface = tex.GetFace((uint)face); // Convert Shininess to PRIM_SHINY_* res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); // PRIM_BUMP_* res.Add(new LSL_Integer((int)texface.Bump)); } } } else if (code == (int)ScriptBaseClass.PRIM_FULLBRIGHT) { if (remain < 1) return res; face = rules.GetLSLIntegerItem(idx++); tex = part.Shape.Textures; if (face == ScriptBaseClass.ALL_SIDES) { for (face = 0; face < GetNumberOfSides(part); face++) { Primitive.TextureEntryFace texface = tex.GetFace((uint)face); res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); } } else { if (face >= 0 && face < GetNumberOfSides(part)) { Primitive.TextureEntryFace texface = tex.GetFace((uint)face); res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); } } } else if (code == (int)ScriptBaseClass.PRIM_FLEXIBLE) { PrimitiveBaseShape shape = part.Shape; res.Add(shape.FlexiEntry ? new LSL_Integer(1) : new LSL_Integer(0)); res.Add(new LSL_Integer(shape.FlexiSoftness)); // softness res.Add(new LSL_Float(shape.FlexiGravity)); // gravity res.Add(new LSL_Float(shape.FlexiDrag)); // friction res.Add(new LSL_Float(shape.FlexiWind)); // wind res.Add(new LSL_Float(shape.FlexiTension)); // tension res.Add(new LSL_Vector(shape.FlexiForceX, // force shape.FlexiForceY, shape.FlexiForceZ)); } else if (code == (int)ScriptBaseClass.PRIM_TEXGEN) { if (remain < 1) return res; face = rules.GetLSLIntegerItem(idx++); if (face == ScriptBaseClass.ALL_SIDES) { for (face = 0; face < GetNumberOfSides(part); face++) { MappingType texgen = tex.GetFace((uint)face).TexMapType; // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. res.Add(new LSL_Integer((uint)texgen >> 1)); } } else { if (face >= 0 && face < GetNumberOfSides(part)) { MappingType texgen = tex.GetFace((uint)face).TexMapType; res.Add(new LSL_Integer((uint)texgen >> 1)); } } } else if (code == (int)ScriptBaseClass.PRIM_POINT_LIGHT) { PrimitiveBaseShape shape = part.Shape; res.Add(shape.LightEntry ? new LSL_Integer(1) : new LSL_Integer(0)); res.Add(new LSL_Vector(shape.LightColorR, // color shape.LightColorG, shape.LightColorB)); res.Add(new LSL_Float(shape.LightIntensity)); // intensity res.Add(new LSL_Float(shape.LightRadius)); // radius res.Add(new LSL_Float(shape.LightFalloff)); // falloff } else if (code == (int)ScriptBaseClass.PRIM_GLOW) { if (remain < 1) return res; face = rules.GetLSLIntegerItem(idx++); if (face == ScriptBaseClass.ALL_SIDES) { for (face = 0; face < GetNumberOfSides(part); face++) { Primitive.TextureEntryFace texface = tex.GetFace((uint)face); res.Add(new LSL_Float(texface.Glow)); } } else { if (face >= 0 && face < GetNumberOfSides(part)) { Primitive.TextureEntryFace texface = tex.GetFace((uint)face); res.Add(new LSL_Float(texface.Glow)); } } } else if (code == (int)ScriptBaseClass.PRIM_TEXT) { Color4 textColor = part.GetTextColor(); res.Add(new LSL_String(part.Text)); res.Add(new LSL_Vector(textColor.R, textColor.G, textColor.B)); res.Add(new LSL_Float(1 - textColor.A)); } else if (code == (int)ScriptBaseClass.PRIM_ROT_LOCAL) { Quaternion rtmp = part.GetRotationOffset(); res.Add(new LSL_Rotation(rtmp.X, rtmp.Y, rtmp.Z, rtmp.W)); } else if (code == (int)ScriptBaseClass.PRIM_OMEGA) { Vector3 axis = part.OmegaAxis; LSL_Float spinRate = part.OmegaSpinRate; LSL_Float gain = part.OmegaGain; res.Add(axis); res.Add(spinRate); res.Add(gain); } else if (code == (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE) { res.Add(new LSL_Integer(part.PhysicsType)); } else if (code == (int)ScriptBaseClass.PRIM_LINK_TARGET) { if (remain < 1) continue; LSL_Integer nextLink = rules.GetLSLIntegerItem(idx++); List<ISceneChildEntity> entities = GetLinkParts(nextLink); if (entities.Count > 0) part = entities[0]; } else if (code == (int)ScriptBaseClass.OS_PRIM_PROJECTION) { if (!allowOpenSimParams) return null; res.Add((LSL_Integer)( part.Shape.ProjectionEntry ? 1 : 0)); res.Add((LSL_Key)part.Shape.ProjectionTextureUUID.ToString()); res.Add((LSL_Float)part.Shape.ProjectionFOV); res.Add((LSL_Float)part.Shape.ProjectionFocus); res.Add((LSL_Float)part.Shape.ProjectionAmbiance); } else if (code == (int)ScriptBaseClass.OS_PRIM_VELOCITY) { if (!allowOpenSimParams) return null; res.Add(new LSL_Vector(part.Velocity)); } else if (code == (int)ScriptBaseClass.OS_PRIM_ACCELERATION) { if (!allowOpenSimParams) return null; res.Add(new LSL_Vector(part.Acceleration)); } } return res; }
public LSL_Rotation llRotBetween(LSL_Vector a, LSL_Vector b) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return new LSL_Rotation(); //A and B should both be normalized LSL_Rotation rotBetween; // Check for zero vectors. If either is zero, return zero rotation. Otherwise, // continue calculation. if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) { rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); } else { a = LSL_Vector.Norm(a); b = LSL_Vector.Norm(b); double dotProduct = LSL_Vector.Dot(a, b); // There are two degenerate cases possible. These are for vectors 180 or // 0 degrees apart. These have to be detected and handled individually. // // Check for vectors 180 degrees apart. // A dot product of -1 would mean the angle between vectors is 180 degrees. if (dotProduct < -0.9999999f) { // First assume X axis is orthogonal to the vectors. LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); // Check for near zero vector. A very small non-zero number here will create // a rotation in an undesired direction. rotBetween = LSL_Vector.Mag(orthoVector) > 0.0001 ? new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f) : new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f); } // Check for parallel vectors. // A dot product of 1 would mean the angle between vectors is 0 degrees. else if (dotProduct > 0.9999999f) { // Set zero rotation. rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); } else { // All special checks have been performed so get the axis of rotation. LSL_Vector crossProduct = LSL_Vector.Cross(a, b); // Quarternion s value is the length of the unit vector + dot product. double qs = 1.0 + dotProduct; rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs); // Normalize the rotation. double mag = LSL_Rotation.Mag(rotBetween); // We shouldn't have to worry about a divide by zero here. The qs value will be // non-zero because we already know if we're here, then the dotProduct is not -1 so // qs will not be zero. Also, we've already handled the input vectors being zero so the // crossProduct vector should also not be zero. rotBetween.x = rotBetween.x / mag; rotBetween.y = rotBetween.y / mag; rotBetween.z = rotBetween.z / mag; rotBetween.s = rotBetween.s / mag; // Check for undefined values and set zero rotation if any found. This code might not actually be required // any longer since zero vectors are checked for at the top. if (double.IsNaN(rotBetween.x) || double.IsNaN(rotBetween.y) || double.IsNaN(rotBetween.z) || double.IsNaN(rotBetween.s)) { rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); } } } return rotBetween; }
/// <summary> /// A partial implementation. /// http://lslwiki.net/lslwiki/wakka.php?wakka=llGetBoundingBox /// So far only valid for standing/flying/ground sitting avatars and single prim objects. /// If the object has multiple prims and/or a sitting avatar then the bounding /// box is for the root prim only. /// </summary> public LSL_List llGetBoundingBox(string obj) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return new LSL_List(); UUID objID = UUID.Zero; LSL_List result = new LSL_List(); if (!UUID.TryParse(obj, out objID)) { result.Add(new LSL_Vector()); result.Add(new LSL_Vector()); return result; } IScenePresence presence = World.GetScenePresence(objID); if (presence != null) { if (presence.ParentID == UUID.Zero) // not sat on an object { LSL_Vector lower = new LSL_Vector(); LSL_Vector upper = new LSL_Vector(); if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) { // This is for ground sitting avatars IAvatarAppearanceModule appearance = presence.RequestModuleInterface<IAvatarAppearanceModule>(); if (appearance != null) { float height = appearance.Appearance.AvatarHeight / 2.66666667f; lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f); upper = new LSL_Vector(0.3375f, 0.45f, 0.0f); } } else { // This is for standing/flying avatars IAvatarAppearanceModule appearance = presence.RequestModuleInterface<IAvatarAppearanceModule>(); if (appearance != null) { float height = appearance.Appearance.AvatarHeight / 2.0f; lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f); upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f); } } result.Add(lower); result.Add(upper); return result; } // sitting on an object so we need the bounding box of that // which should include the avatar so set the UUID to the // UUID of the object the avatar is sat on and allow it to fall through // to processing an object ISceneChildEntity p = World.GetSceneObjectPart(presence.ParentID); objID = p.UUID; } ISceneChildEntity part = World.GetSceneObjectPart(objID); // Currently only works for single prims without a sitting avatar if (part != null) { Vector3 halfSize = part.Scale * 0.5f; LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); result.Add(lower); result.Add(upper); return result; } // Not found so return empty values result.Add(new LSL_Vector()); result.Add(new LSL_Vector()); return result; }
protected void SetPrimitiveShapeParams(ISceneChildEntity part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte fudge) { ObjectShapePacket.ObjectDataBlock shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); shapeBlock.ProfileCurve += fudge; // profile/path swapped for a torrus, tube, ring shapeBlock.PathBegin = shapeBlock.ProfileBegin; shapeBlock.PathEnd = shapeBlock.ProfileEnd; if (holesize.x < 0.01f) { holesize.x = 0.01f; } if (holesize.x > 1f) { holesize.x = 1f; } if (holesize.y < 0.01f) { holesize.y = 0.01f; } if (holesize.y > 0.5f) { holesize.y = 0.5f; } float tempFloat = (float)(100.0d * (2.0d - holesize.x)); shapeBlock.PathScaleX = (byte)tempFloat; tempFloat = (float)(100.0d * (2.0d - holesize.y)); shapeBlock.PathScaleY = (byte)tempFloat; if (topshear.x < -0.5f) { topshear.x = -0.5f; } if (topshear.x > 0.5f) { topshear.x = 0.5f; } if (topshear.y < -0.5f) { topshear.y = -0.5f; } if (topshear.y > 0.5f) { topshear.y = 0.5f; } tempFloat = (float)(100.0d * topshear.x); shapeBlock.PathShearX = (byte)tempFloat; tempFloat = (float)(100.0d * topshear.y); shapeBlock.PathShearY = (byte)tempFloat; if (profilecut.x < 0f) { profilecut.x = 0f; } if (profilecut.x > 1f) { profilecut.x = 1f; } if (profilecut.y < 0f) { profilecut.y = 0f; } if (profilecut.y > 1f) { profilecut.y = 1f; } if (profilecut.y - profilecut.x < 0.02f) { profilecut.x = profilecut.y - 0.02f; if (profilecut.x < 0.0f) { profilecut.x = 0.0f; profilecut.y = 0.02f; } } shapeBlock.ProfileBegin = (ushort)(50000 * profilecut.x); shapeBlock.ProfileEnd = (ushort)(50000 * (1 - profilecut.y)); if (taper_a.x < -1f) { taper_a.x = -1f; } if (taper_a.x > 1f) { taper_a.x = 1f; } if (taper_a.y < -1f) { taper_a.y = -1f; } if (taper_a.y > 1f) { taper_a.y = 1f; } tempFloat = (float)(100.0d * taper_a.x); shapeBlock.PathTaperX = (sbyte)tempFloat; tempFloat = (float)(100.0d * taper_a.y); shapeBlock.PathTaperY = (sbyte)tempFloat; if (revolutions < 1f) { revolutions = 1f; } if (revolutions > 4f) { revolutions = 4f; } tempFloat = 66.66667f * (revolutions - 1.0f); shapeBlock.PathRevolutions = (byte)tempFloat; // limits on radiusoffset depend on revolutions and hole size (how?) seems like the maximum range is 0 to 1 if (radiusoffset < 0f) { radiusoffset = 0f; } if (radiusoffset > 1f) { radiusoffset = 1f; } tempFloat = 100.0f * radiusoffset; shapeBlock.PathRadiusOffset = (sbyte)tempFloat; if (skew < -0.95f) { skew = -0.95f; } if (skew > 0.95f) { skew = 0.95f; } tempFloat = 100.0f * skew; shapeBlock.PathSkew = (sbyte)tempFloat; part.Shape.SculptEntry = false; part.UpdateShape(shapeBlock); }
protected void SetPrimitiveShapeParams(ISceneChildEntity part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge) { ObjectShapePacket.ObjectDataBlock shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); // profile/path swapped for a sphere shapeBlock.PathBegin = shapeBlock.ProfileBegin; shapeBlock.PathEnd = shapeBlock.ProfileEnd; shapeBlock.ProfileCurve += fudge; shapeBlock.PathScaleX = 100; shapeBlock.PathScaleY = 100; if (dimple.x < 0f) { dimple.x = 0f; } if (dimple.x > 1f) { dimple.x = 1f; } if (dimple.y < 0f) { dimple.y = 0f; } if (dimple.y > 1f) { dimple.y = 1f; } if (dimple.y - dimple.x < 0.02f) { dimple.x = dimple.y - 0.02f; if (dimple.x < 0.0f) { dimple.x = 0.0f; dimple.y = 0.02f; } } shapeBlock.ProfileBegin = (ushort)(50000 * dimple.x); shapeBlock.ProfileEnd = (ushort)(50000 * (1 - dimple.y)); part.Shape.SculptEntry = false; part.UpdateShape(shapeBlock); }
protected void SetPrimitiveShapeParams(ISceneChildEntity part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge) { ObjectShapePacket.ObjectDataBlock shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); shapeBlock.ProfileCurve += fudge; if (taper_b.x < 0f) { taper_b.x = 0f; } if (taper_b.x > 2f) { taper_b.x = 2f; } if (taper_b.y < 0f) { taper_b.y = 0f; } if (taper_b.y > 2f) { taper_b.y = 2f; } float tempFloat = (float)(100.0d * (2.0d - taper_b.x)); shapeBlock.PathScaleX = (byte)tempFloat; tempFloat = (float)(100.0d * (2.0d - taper_b.y)); shapeBlock.PathScaleY = (byte)tempFloat; if (topshear.x < -0.5f) { topshear.x = -0.5f; } if (topshear.x > 0.5f) { topshear.x = 0.5f; } if (topshear.y < -0.5f) { topshear.y = -0.5f; } if (topshear.y > 0.5f) { topshear.y = 0.5f; } tempFloat = (float)(100.0d * topshear.x); shapeBlock.PathShearX = (byte)tempFloat; tempFloat = (float)(100.0d * topshear.y); shapeBlock.PathShearY = (byte)tempFloat; part.Shape.SculptEntry = false; part.UpdateShape(shapeBlock); }
public LSL_String llGetLandOwnerAt(LSL_Vector pos) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return ""; IParcelManagementModule parcelManagement = World.RequestModuleInterface<IParcelManagementModule>(); if (parcelManagement != null) { ILandObject land = parcelManagement.GetLandObject((float)pos.x, (float)pos.y); if (land != null) return land.LandData.OwnerID.ToString(); } return UUID.Zero.ToString(); }
public LSL_Vector llGroundSlope(LSL_Vector offset) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return new LSL_Vector(); //Get the slope normal. This gives us the equation of the plane tangent to the slope. LSL_Vector vsn = llGroundNormal(offset); //Plug the x,y coordinates of the slope normal into the equation of the plane to get //the height of that point on the plane. The resulting vector gives the slope. Vector3 vsl = new Vector3 { X = (float)vsn.x, Y = (float)vsn.y, Z = (float)(((vsn.x * vsn.x) + (vsn.y * vsn.y)) / (-1 * vsn.z)) }; vsl.Normalize(); //Normalization might be overkill here return new LSL_Vector(vsl.X, vsl.Y, vsl.Z); }
public LSL_Integer llEdgeOfWorld(LSL_Vector pos, LSL_Vector dir) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return 0; // edge will be used to pass the Region Coordinates offset // we want to check for a neighboring sim LSL_Vector edge = new LSL_Vector(0, 0, 0); if (dir.x == 0) { if (dir.y == 0) { // Direction vector is 0,0 so return // false since we're staying in the sim return 0; } // Y is the only valid direction edge.y = dir.y / Math.Abs(dir.y); } else { LSL_Float mag; if (dir.x > 0) { mag = (World.RegionInfo.RegionSizeX - pos.x) / dir.x; } else { mag = (pos.x / dir.x); } mag = Math.Abs(mag); edge.y = pos.y + (dir.y * mag); if (edge.y > World.RegionInfo.RegionSizeY || edge.y < 0) { // Y goes out of bounds first edge.y = dir.y / Math.Abs(dir.y); } else { // X goes out of bounds first or its a corner exit edge.y = 0; edge.x = dir.x / Math.Abs(dir.x); } } IGridRegisterModule service = World.RequestModuleInterface<IGridRegisterModule>(); List<GridRegion> neighbors = new List<GridRegion>(); if (service != null) neighbors = service.GetNeighbors(World); int neighborX = World.RegionInfo.RegionLocX + (int)dir.x; int neighborY = World.RegionInfo.RegionLocY + (int)dir.y; if (neighbors.Any(neighbor => neighbor.RegionLocX == neighborX && neighbor.RegionLocY == neighborY)) { return LSL_Integer.TRUE; } return LSL_Integer.FALSE; }
public void botSitObject(string bot, string objectID, LSL_Vector offset) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.Moderate, "botTouchObject", m_host, "bot", m_itemID)) return; IScenePresence sp = World.GetScenePresence(UUID.Parse(bot)); if (sp == null) return; ISceneChildEntity child = World.GetSceneObjectPart(UUID.Parse(objectID)); if (child == null) throw new Exception("Failed to find entity to sit on"); sp.HandleAgentRequestSit(sp.ControllingClient, UUID.Parse(objectID), new Vector3((float) offset.x, (float) offset.y, (float) offset.z)); }
public void llSetLinkCamera(LSL_Integer link, LSL_Vector eye, LSL_Vector at) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return; List<ISceneChildEntity> entities = GetLinkParts(link); if (entities.Count > 0) { entities[0].CameraEyeOffset = new Vector3((float)eye.x, (float)eye.y, (float)eye.z); entities[0].CameraAtOffset = new Vector3((float)at.x, (float)at.y, (float)at.z); } }
public LSL_Vector llGroundContour(LSL_Vector offset) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return new LSL_Vector(); LSL_Vector x = llGroundSlope(offset); return new LSL_Vector(-x.y, x.x, 0.0); }
public void llSitTarget(LSL_Vector offset, LSL_Rotation rot) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return; SitTarget (m_host, offset, rot); }
//This next group are vector operations involving squaring and square root. ckrinke public LSL_Float llVecMag(LSL_Vector v) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return new LSL_Float(); return LSL_Vector.Mag(v); }
/* From wiki: The Euler angle vector (in radians) is converted to a rotation by doing the rotations around the 3 axes in Z, Y, X order. So llEuler2Rot(<1.0, 2.0, 3.0> * DEG_TO_RAD) generates a rotation by taking the zero rotation, a vector pointing along the X axis, first rotating it 3 degrees around the global Z axis, then rotating the resulting vector 2 degrees around the global Y axis, and finally rotating that 1 degree around the global X axis. */ /* How we arrived at this llEuler2Rot * * Experiment in SL to determine conventions: * llEuler2Rot(<PI,0,0>)=<1,0,0,0> * llEuler2Rot(<0,PI,0>)=<0,1,0,0> * llEuler2Rot(<0,0,PI>)=<0,0,1,0> * * Important facts about Quaternions * - multiplication is non-commutative (a*b != b*a) * - http://en.wikipedia.org/wiki/Quaternion#Basis_multiplication * * Above SL experiment gives (c1,c2,c3,s1,s2,s3 as defined in our llEuler2Rot): * Qx = c1+i*s1 * Qy = c2+j*s2; * Qz = c3+k*s3; * * Rotations applied in order (from above) Z, Y, X * Q = (Qz * Qy) * Qx * ((c1+i*s1)*(c2+j*s2))*(c3+k*s3) * (c1*c2+i*s1*c2+j*c1*s2+ij*s1*s2)*(c3+k*s3) * (c1*c2+i*s1*c2+j*c1*s2+k*s1*s2)*(c3+k*s3) * c1*c2*c3+i*s1*c2*c3+j*c1*s2*c3+k*s1*s2*c3+k*c1*c2*s3+ik*s1*c2*s3+jk*c1*s2*s3+kk*s1*s2*s3 * c1*c2*c3+i*s1*c2*c3+j*c1*s2*c3+k*s1*s2*c3+k*c1*c2*s3 -j*s1*c2*s3 +i*c1*s2*s3 -s1*s2*s3 * regroup: x=i*(s1*c2*c3+c1*s2*s3) * y=j*(c1*s2*c3-s1*c2*s3) * z=k*(s1*s2*c3+c1*c2*s3) * s= c1*c2*c3-s1*s2*s3 * * This implementation agrees with the functions found here: * http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions * And with the results in SL. * * It's also possible to calculate llEuler2Rot by direct multiplication of * the Qz, Qy, and Qx vectors (as above - and done in the "accurate" function * from the wiki). * Apparently in some cases this is better from a numerical precision perspective? */ public LSL_Rotation llEuler2Rot(LSL_Vector v) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return new LSL_Rotation(); double c1 = Math.Cos(v.x * 0.5); double c2 = Math.Cos(v.y * 0.5); double c3 = Math.Cos(v.z * 0.5); double s1 = Math.Sin(v.x * 0.5); double s2 = Math.Sin(v.y * 0.5); double s3 = Math.Sin(v.z * 0.5); double x = s1 * c2 * c3 + c1 * s2 * s3; double y = c1 * s2 * c3 - s1 * c2 * s3; double z = s1 * s2 * c3 + c1 * c2 * s3; double s = c1 * c2 * c3 - s1 * s2 * s3; return new LSL_Rotation(x, y, z, s); }
public LSL_Integer llScriptDanger(LSL_Vector pos) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return 0; bool result = m_ScriptEngine.PipeEventsForScript(m_host, new Vector3((float)pos.x, (float)pos.y, (float)pos.z)); if (result) { return 1; } return 0; }
public void llSetVehicleVectorParam(int param, LSL_Vector vec) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return; if (m_host.ParentEntity != null) { if (!m_host.ParentEntity.IsDeleted) { m_host.ParentEntity.RootChild.SetVehicleVectorParam(param, new Vector3((float)vec.x, (float)vec.y, (float)vec.z)); } } }
public void llSetCameraAtOffset(LSL_Vector offset) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return; m_host.CameraAtOffset = new Vector3((float)offset.x, (float)offset.y, (float)offset.z); }
public LSL_Vector llVecNorm(LSL_Vector v) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return new LSL_Vector(); return LSL_Vector.Norm(v); }
public LSL_Rotation llAxes2Rot(LSL_Vector fwd, LSL_Vector left, LSL_Vector up) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return new LSL_Rotation(); double s; double tr = fwd.x + left.y + up.z + 1.0; if (tr >= 1.0) { s = 0.5 / Math.Sqrt(tr); return new LSL_Rotation( (left.z - up.y) * s, (up.x - fwd.z) * s, (fwd.y - left.x) * s, 0.25 / s); } double max = (left.y > up.z) ? left.y : up.z; if (max < fwd.x) { s = Math.Sqrt(fwd.x - (left.y + up.z) + 1.0); double x = s * 0.5; s = 0.5 / s; return new LSL_Rotation( x, (fwd.y + left.x) * s, (up.x + fwd.z) * s, (left.z - up.y) * s); } if (FloatAlmostEqual(max,left.y)) { s = Math.Sqrt(left.y - (up.z + fwd.x) + 1.0); double y = s * 0.5; s = 0.5 / s; return new LSL_Rotation( (fwd.y + left.x) * s, y, (left.z + up.y) * s, (up.x - fwd.z) * s); } s = Math.Sqrt(up.z - (fwd.x + left.y) + 1.0); double z = s * 0.5; s = 0.5 / s; return new LSL_Rotation( (up.x + fwd.z) * s, (left.z + up.y) * s, z, (fwd.y - left.x) * s); }
protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(ISceneChildEntity part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist) { ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && holeshape != (int)ScriptBaseClass.PRIM_HOLE_SQUARE && holeshape != (int)ScriptBaseClass.PRIM_HOLE_TRIANGLE) { holeshape = ScriptBaseClass.PRIM_HOLE_DEFAULT; } shapeBlock.ProfileCurve = (byte)holeshape; if (cut.x < 0f) { cut.x = 0f; } if (cut.x > 1f) { cut.x = 1f; } if (cut.y < 0f) { cut.y = 0f; } if (cut.y > 1f) { cut.y = 1f; } if (cut.y - cut.x < 0.02f) { cut.x = cut.y - 0.02f; if (cut.x < 0.0f) { cut.x = 0.0f; cut.y = 0.02f; } } shapeBlock.ProfileBegin = (ushort)(50000 * cut.x); shapeBlock.ProfileEnd = (ushort)(50000 * (1 - cut.y)); if (hollow < 0f) { hollow = 0f; } if (hollow > 0.99) { hollow = 0.99f; } shapeBlock.ProfileHollow = (ushort)(50000 * hollow); if (twist.x < -1.0f) { twist.x = -1.0f; } if (twist.x > 1.0f) { twist.x = 1.0f; } if (twist.y < -1.0f) { twist.y = -1.0f; } if (twist.y > 1.0f) { twist.y = 1.0f; } // A fairly large precision error occurs for some calculations, // if a float or double is directly cast to a byte or sbyte // variable, in both .Net and Mono. In .Net, coding // "(sbyte)(float)(some expression)" corrects the precision // errors. But this does not work for Mono. This longer coding // form of creating a tempoary float variable from the // expression first, then casting that variable to a byte or // sbyte, works for both .Net and Mono. These types of // assignments occur in SetPrimtiveBlockShapeParams and // SetPrimitiveShapeParams in support of llSetPrimitiveParams. float tempFloat = (float)(100.0d * twist.x); shapeBlock.PathTwistBegin = (sbyte)tempFloat; tempFloat = (float)(100.0d * twist.y); shapeBlock.PathTwist = (sbyte)tempFloat; shapeBlock.ObjectLocalID = part.LocalId; // retain pathcurve shapeBlock.PathCurve = part.Shape.PathCurve; part.Shape.SculptEntry = false; return shapeBlock; }
public LSL_Float llVecDist(LSL_Vector a, LSL_Vector b) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return new LSL_Float(); double dx = a.x - b.x; double dy = a.y - b.y; double dz = a.z - b.z; return Math.Sqrt(dx * dx + dy * dy + dz * dz); }