public ContactResult Submit(ContactModel contact, ContactSettings contactSettings) { var result = new ContactResult(); if (contact == null) throw new ArgumentNullException("Missing contact form data"); if (contactSettings == null) throw new ArgumentNullException("Missing settings"); if (logger != null) logger.LogInformation("Contact: {0} / {1} / {2} [Email: {3}, Post: {4}, Recaptcha: {5}]", contact.ContactName, contact.Email, contact.Phone, contactSettings.EmailSettings?.Enabled, contactSettings.PostSettings?.Enabled, contactSettings.RecaptchaSettings?.Enabled); if (contactSettings.RecaptchaSettings != null && contactSettings.RecaptchaSettings.Enabled && !string.IsNullOrEmpty(contactSettings.RecaptchaSettings.RecaptchaKey)) { // Check Recaptcha var recaptchaService = new RecaptchaService(); result.RecaptchaResult = recaptchaService.Validate(contactSettings.RecaptchaSettings, logger); if (result.RecaptchaResult.ServiceResultType != ServiceResultType.Success) return result; // Stop processing immediately } if (contactSettings.EmailSettings != null && contactSettings.EmailSettings.Enabled) { var emailService = new EmailService(); result.EmailResult = emailService.SendEmail(contact, contactSettings.EmailSettings, logger); } if (contactSettings.PostSettings != null && contactSettings.PostSettings.Enabled && !string.IsNullOrEmpty(contactSettings.PostSettings.PostURL)) { var postService = new PostService(); result.PostResult = postService.Post(contact, contactSettings.PostSettings, logger); } return result; }
public string GetResultHTML(ContactResult result, ContactSettings contactSettings) { StringBuilder sbResult = new StringBuilder(); sbResult.AppendLine(result.Success ? "Successfully executed: <br />" : "Execution result: <br />"); if (result.EmailResult != null && result.EmailResult.ServiceResultType != ServiceResultType.None) sbResult.AppendFormat("{0} <br/>", result.EmailResult.Message); if (result.PostResult != null && result.PostResult.ServiceResultType != ServiceResultType.None) sbResult.AppendFormat("{0} <br/>", result.PostResult.Message); if (result.RecaptchaResult != null && result.RecaptchaResult.ServiceResultType != ServiceResultType.Success) sbResult.AppendFormat("Invalid reCAPTCHA: {0} <br/>", result.RecaptchaResult.Message); if (!string.IsNullOrEmpty(contactSettings.PostSettings.RedirectURL) && contactSettings.PostSettings.RedirectSeconds >= 0) { var redirectURL = string.Format(contactSettings.PostSettings.RedirectURL, result.Success ? "1" : "0"); // Show 'Click to continue' sbResult.AppendFormat("<a href='{0}'>{1}</a>", redirectURL, contactSettings.PostSettings.RedirectText); if (contactSettings.PostSettings.RedirectSeconds > 0) { // JS redirect after RedirectSeconds sbResult.AppendFormat("\r\n<script type='text/javascript'>setTimeout(function() {{document.location.href='{0}'}}, {1})</script>", redirectURL, contactSettings.PostSettings.RedirectSeconds * 1000); } } return sbResult.ToString(); }
public static AlienResult ConvertToResult( Alien alien, ContactResult contactResult, PassportResult passportResult, OrganizationResult organizationResult, StateRegistrationResult stateRegistrationResult) { Contract.Argument.IsNotNull(alien, nameof(alien)); Contract.Argument.IsNotNull(contactResult, nameof(contactResult)); Contract.Argument.IsNotNull(passportResult, nameof(passportResult)); Contract.Argument.IsNotNull(organizationResult, nameof(organizationResult)); Contract.Argument.IsNotNull(stateRegistrationResult, nameof(stateRegistrationResult)); return(new AlienResult { Id = alien.Id, InvitationId = alien.InvitationId, Contact = contactResult, Passport = passportResult, Organization = organizationResult, StateRegistration = stateRegistrationResult, Position = alien.Position, WorkPlace = alien.WorkPlace, WorkAddress = alien.WorkAddress, StayAddress = alien.StayAddress }); }
private void backgroundWorkerContact_DoWork(object sender, DoWorkEventArgs e) { WechatRobot robot = Global.robot; ContactResult contact = protocol.GetContact(robot.Cookie, robot.CookieStr); e.Result = contact; }
private void ExtractCollisionData(ContactResult point, out Projectile proj, out Alien alien, out Player player, out Pickup pickup) { proj = null; alien = null; player = null; pickup = null; var shapes = new Shape[] { point.Shape1, point.Shape2 }; foreach (var shape in shapes) { if (shape.UserData is Projectile && proj == null) { proj = shape.UserData as Projectile; } else if (shape.UserData is Alien) { alien = shape.UserData as Alien; } else if (shape.UserData is Player) { player = shape.UserData as Player; } else if (shape.UserData is Pickup) { pickup = shape.UserData as Pickup; } } }
protected void Button1_Click(object sender, EventArgs e) { ContactResult cr = new ContactResult(); GlobalVar var = new GlobalVar(); try { SqlDataAdapter da = new SqlDataAdapter(); using (SqlConnection openCon = new SqlConnection(var.connectionString)) { string saveStaff = "SELECT [AndroidLog],[AndroidLat] FROM [AndroidTrack] where [DateRegister]= (select max([DateRegister]) from AndroidTrack)"; using (SqlCommand querySaveStaff = new SqlCommand(saveStaff)) { querySaveStaff.Connection = openCon; DataSet ds = new DataSet(); openCon.Open(); DataTable table = new DataTable(); table.Load(querySaveStaff.ExecuteReader()); ds.Tables.Add(table); Response.Redirect("http://www.google.com/maps/place/" + Convert.ToString(table.Rows[0]["AndroidLat"]) + "," + Convert.ToString(table.Rows[0]["AndroidLog"])); openCon.Close(); } } } catch (Exception ex) { Response.Write(ex.Message); } }
private void backgroundWorkerContact_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { ContactResult contact = e.Result as ContactResult; InitContact(contact.MemberList); Global.robot.Contact = contact.MemberList.ToList(); LogOut("联系人获取完成"); }
private void BallContact(ContactResult point) { Shape shape1 = point.Shape1, shape2 = point.Shape2; Body body1 = point.Shape1.GetBody(), body2 = point.Shape2.GetBody(); float ballTackleSpeed; Body anotherBody; if ((anotherBody = this.GetAnotherBodyInContact(point, this.ball)) == null) { return; } if (anotherBody == this.goalLeft) { this.ball.ApplyForce(new Vec2(0.005f, 0), this.ball.GetPosition()); if (shape1.UserData as string == "Post" || shape2.UserData as string == "Post") { if ((ballTackleSpeed = this.GetBallCollisionSpeed()) > 0.02f) { this.BallPostTackled(ballTackleSpeed); } return; } } if (anotherBody == this.goalRight) { this.ball.ApplyForce(new Vec2(-0.005f, 0), this.ball.GetPosition()); if (shape1.UserData as string == "Post" || shape2.UserData as string == "Post") { if ((ballTackleSpeed = this.GetBallCollisionSpeed()) > 0.02f) { this.BallPostTackled(ballTackleSpeed); } return; } } if (anotherBody == this.ground) { if (this.ball.GetAngularVelocity() * 0.15 * (this.ball.GetAngularVelocity() > 0 ? 1 : -1) > 0.85 * this.ball.GetLinearVelocity().X *(this.ball.GetLinearVelocity().X > 0 ? 1 : -1)) { this.ball.SetAngularVelocity(this.ball.GetAngularVelocity() * 0.94f); } } if ((ballTackleSpeed = this.GetBallCollisionSpeed()) > 0.02f) { this.BallTackled?.Invoke(ballTackleSpeed); } }
private Person GetPersonDetails(KerberosResult ucdKerbPerson, ContactResult ucdContact) { return(new Person { GivenName = string.IsNullOrWhiteSpace(ucdKerbPerson.DFirstName) ? ucdKerbPerson.OFirstName : ucdKerbPerson.DFirstName, Surname = string.IsNullOrWhiteSpace(ucdKerbPerson.DLastName) ? ucdKerbPerson.OLastName : ucdKerbPerson.DLastName, FullName = string.IsNullOrWhiteSpace(ucdKerbPerson.DFullName) ? ucdKerbPerson.OFullName : ucdKerbPerson.DFullName, Kerberos = ucdKerbPerson.UserId, Mail = ucdContact.Email, WorkPhone = ucdContact.WorkPhone }); }
private Body GetAnotherBodyInContact(ContactResult point, Body body) { Body body1 = point.Shape1.GetBody(), body2 = point.Shape2.GetBody(); if (body1 != body && body2 != body) { return(null); } if (body1 == body) { return(body2); } else { return(body1); } }
public static async Task <ContactResult> GetContactUs(string url) { ContactResult objData = new ContactResult(); try { using (var client = new HttpClient()) { client.BaseAddress = new Uri(url); var result = await client.GetAsync(url); var place = result.Content.ReadAsStringAsync().Result; objData = JsonConvert.DeserializeObject <ContactResult>(await result.Content.ReadAsStringAsync()); } } catch (Exception ex) { } return(objData); }
/// <summary> /// 获取联系人信息 /// </summary> /// <returns></returns> public ContactResult GetContact(WechatCookie wechatCookie, string cookieStr) { string url = string.Format(WechatUrl.ContentUrl, wechatCookie.Pass_Ticket, WechatCommon.GetTicks(), wechatCookie.Skey); string html = HttpCommon.instance.PostHttp(url, "{}", ContentType.json, cookieStr); AppLog.WriteInfo(string.Format("协议:{0},结果:{1}", "GetContact", html)); ContactResult contact = new ContactResult(); try { if (!string.IsNullOrEmpty(html) && html != "操作超时") { contact = JsonConvert.DeserializeObject <ContactResult>(html); } } catch (Exception ex) { AppLog.WriteError(ex.Message); } return(contact); }
public override void Result(ContactResult point) { Projectile proj = null; Alien alien = null; Player player = null; Pickup pickup = null; ExtractCollisionData(point, out proj, out alien, out player, out pickup); if (proj != null) { if (proj.Active) { if (alien != null) { Logger.Info("projectile collided with alien"); alien.OnCollision(proj, point.Position); proj.OnCollision(alien, point.Position); } else if (player != null) { Logger.Info("projectile collided with player"); player.OnCollision(proj, point.Position); proj.OnCollision(player, point.Position); } } } else if (pickup != null && player != null) { pickup.OnCollision(player, point.Position); player.OnCollision(pickup, point.Position); } else { base.Result(point); } }
public static EmployeeResult ConvertToResult( Employee employee, ContactResult contactResult, PassportResult passportResult, OrganizationResult organizationResult, StateRegistrationResult stateRegistrationResult) { Contract.Argument.IsNotNull(employee, nameof(employee)); return(new EmployeeResult { Id = employee.Id, Contact = contactResult, Passport = passportResult, Organization = organizationResult, StateRegistration = stateRegistrationResult, ManagerId = employee.ManagerId, AcademicDegree = employee.AcademicDegree, AcademicRank = employee.AcademicRank, Education = employee.Education, Position = employee.Position, WorkPlace = employee.WorkPlace }); }
// don't like this public override List<ContactResult> RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count) { if (actor != null) { IntPtr geom; if (actor is OdePrim) geom = ((OdePrim)actor).prim_geom; else if (actor is OdeCharacter) geom = ((OdePrim)actor).prim_geom; else return new List<ContactResult>(); if (geom == IntPtr.Zero) return new List<ContactResult>(); ContactResult[] ourResults = null; RayCallback retMethod = delegate(List<ContactResult> results) { ourResults = new ContactResult[results.Count]; results.CopyTo(ourResults, 0); }; int waitTime = 0; m_rayCastManager.QueueRequest(geom,position, direction, length, Count, retMethod); while (ourResults == null && waitTime < 1000) { Thread.Sleep(1); waitTime++; } if (ourResults == null) return new List<ContactResult>(); return new List<ContactResult>(ourResults); } return new List<ContactResult>(); }
private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd) { List<ContactResult> contacts = new List<ContactResult>(); Vector3 ab = rayEnd - rayStart; World.ForEachScenePresence(delegate(ScenePresence sp) { Vector3 ac = sp.AbsolutePosition - rayStart; // Vector3 bc = sp.AbsolutePosition - rayEnd; double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd)); if (d > 1.5) return; double d2 = Vector3.Dot(Vector3.Negate(ab), ac); if (d2 > 0) return; double dp = Math.Sqrt(Vector3.Mag(ac) * Vector3.Mag(ac) - d * d); Vector3 p = rayStart + Vector3.Divide(Vector3.Multiply(ab, (float)dp), (float)Vector3.Mag(ab)); if (!InBoundingBox(sp, p)) return; ContactResult result = new ContactResult (); result.ConsumerID = sp.LocalId; result.Depth = Vector3.Distance(rayStart, p); result.Normal = Vector3.Zero; result.Pos = p; contacts.Add(result); }); return contacts.ToArray(); }
// This is the standard Near. g1 is the ray private void near(IntPtr space, IntPtr g1, IntPtr g2) { if (g2 == IntPtr.Zero || g1 == g2) { return; } if (m_contactResults.Count >= CurrentMaxCount) { return; } if (SafeNativeMethods.GeomIsSpace(g2)) { try { SafeNativeMethods.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback); } catch (Exception e) { m_log.WarnFormat("[PHYSICS Ray]: Unable to Space collide test an object: {0}", e.Message); } return; } int count = 0; try { count = SafeNativeMethods.CollidePtr(g1, g2, CollisionContactGeomsPerTest, m_scene.ContactgeomsArray, SafeNativeMethods.ContactGeom.unmanagedSizeOf); } catch (Exception e) { m_log.WarnFormat("[PHYSICS Ray]: Unable to collide test an object: {0}", e.Message); return; } if (count == 0) { return; } /* * uint cat1 = d.GeomGetCategoryBits(g1); * uint cat2 = d.GeomGetCategoryBits(g2); * uint col1 = d.GeomGetCollideBits(g1); * uint col2 = d.GeomGetCollideBits(g2); */ uint ID = 0; PhysicsActor p2 = null; m_scene.actor_name_map.TryGetValue(g2, out p2); if (p2 == null) { return; } switch (p2.PhysicsActorType) { case (int)ActorTypes.Prim: RayFilterFlags thisFlags; if (p2.IsPhysical) { thisFlags = RayFilterFlags.physical; } else { thisFlags = RayFilterFlags.nonphysical; } if (p2.Phantom) { thisFlags |= RayFilterFlags.phantom; } if (p2.IsVolumeDtc) { thisFlags |= RayFilterFlags.volumedtc; } if ((thisFlags & CurrentRayFilter) == 0) { return; } ID = ((OdePrim)p2).LocalID; break; case (int)ActorTypes.Agent: if ((CurrentRayFilter & RayFilterFlags.agent) == 0) { return; } else { ID = ((OdeCharacter)p2).LocalID; } break; case (int)ActorTypes.Ground: if ((CurrentRayFilter & RayFilterFlags.land) == 0) { return; } break; case (int)ActorTypes.Water: if ((CurrentRayFilter & RayFilterFlags.water) == 0) { return; } break; default: break; } SafeNativeMethods.ContactGeom curcontact = new SafeNativeMethods.ContactGeom(); // closestHit for now only works for meshs, so must do it for others if ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0) { // Loop all contacts, build results. for (int i = 0; i < count; i++) { if (!GetCurContactGeom(i, ref curcontact)) { break; } ContactResult collisionresult = new ContactResult(); collisionresult.ConsumerID = ID; collisionresult.Pos.X = curcontact.pos.X; collisionresult.Pos.Y = curcontact.pos.Y; collisionresult.Pos.Z = curcontact.pos.Z; collisionresult.Depth = curcontact.depth; collisionresult.Normal.X = curcontact.normal.X; collisionresult.Normal.Y = curcontact.normal.Y; collisionresult.Normal.Z = curcontact.normal.Z; lock (m_contactResults) { m_contactResults.Add(collisionresult); if (m_contactResults.Count >= CurrentMaxCount) { return; } } } } else { // keep only closest contact ContactResult collisionresult = new ContactResult(); collisionresult.ConsumerID = ID; collisionresult.Depth = float.MaxValue; for (int i = 0; i < count; i++) { if (!GetCurContactGeom(i, ref curcontact)) { break; } if (curcontact.depth < collisionresult.Depth) { collisionresult.Pos.X = curcontact.pos.X; collisionresult.Pos.Y = curcontact.pos.Y; collisionresult.Pos.Z = curcontact.pos.Z; collisionresult.Depth = curcontact.depth; collisionresult.Normal.X = curcontact.normal.X; collisionresult.Normal.Y = curcontact.normal.Y; collisionresult.Normal.Z = curcontact.normal.Z; } } if (collisionresult.Depth != float.MaxValue) { lock (m_contactResults) m_contactResults.Add(collisionresult); } } }
public override void Result(ContactResult point) { base.Result(point); onResult?.Invoke((InfoBody)point.Shape1.GetBody().GetUserData(), (InfoBody)point.Shape2.GetBody().GetUserData()); }
public override void Result(ContactResult point) { base.Result(point); OnResult?.Invoke((MyModel3D)point.Shape1.GetBody().GetUserData(), (MyModel3D)point.Shape2.GetBody().GetUserData()); }
public override List<ContactResult> RaycastWorld(Vector3 position, Vector3 direction, float length, int Count) { ContactResult[] ourResults = null; RayCallback retMethod = delegate(List<ContactResult> results) { ourResults = new ContactResult[results.Count]; results.CopyTo(ourResults, 0); }; int waitTime = 0; m_rayCastManager.QueueRequest(position, direction, length, Count, retMethod); while (ourResults == null && waitTime < 1000) { Thread.Sleep(1); waitTime++; } if (ourResults == null) return new List<ContactResult>(); return new List<ContactResult>(ourResults); }
// This is the standard Near. Uses space AABBs to speed up detection. private void near(IntPtr space, IntPtr g1, IntPtr g2) { if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) { return; } // if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass || d.GeomGetClass(g2) == d.GeomClassID.HeightfieldClass) // return; // Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms. if (SafeNativeMethods.GeomIsSpace(g1) || SafeNativeMethods.GeomIsSpace(g2)) { if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) { return; } // Separating static prim geometry spaces. // We'll be calling near recursivly if one // of them is a space to find all of the // contact points in the space try { SafeNativeMethods.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback); } catch (AccessViolationException) { m_log.Warn("[PHYSICS]: Unable to collide test a space"); return; } //Colliding a space or a geom with a space or a geom. so drill down //Collide all geoms in each space.. //if (d.GeomIsSpace(g1)) d.SpaceCollide(g1, IntPtr.Zero, nearCallback); //if (d.GeomIsSpace(g2)) d.SpaceCollide(g2, IntPtr.Zero, nearCallback); return; } if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) { return; } int count = 0; try { if (g1 == g2) { return; // Can't collide with yourself } lock (contacts) { count = SafeNativeMethods.Collide(g1, g2, contacts.GetLength(0), contacts, SafeNativeMethods.ContactGeom.unmanagedSizeOf); } } catch (SEHException) { m_log.Error("[PHYSICS]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim."); } catch (Exception e) { m_log.WarnFormat("[PHYSICS]: Unable to collide test an object: {0}", e.Message); return; } PhysicsActor p1 = null; PhysicsActor p2 = null; if (g1 != IntPtr.Zero) { m_scene.actor_name_map.TryGetValue(g1, out p1); } if (g2 != IntPtr.Zero) { m_scene.actor_name_map.TryGetValue(g1, out p2); } // Loop over contacts, build results. for (int i = 0; i < count; i++) { if (p1 != null) { if (p1 is OdePrim) { ContactResult collisionresult = new ContactResult(); collisionresult.ConsumerID = p1.LocalID; collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z); collisionresult.Depth = contacts[i].depth; collisionresult.Normal = new Vector3(contacts[i].normal.X, contacts[i].normal.Y, contacts[i].normal.Z); lock (m_contactResults) m_contactResults.Add(collisionresult); } } if (p2 != null) { if (p2 is OdePrim) { ContactResult collisionresult = new ContactResult(); collisionresult.ConsumerID = p2.LocalID; collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z); collisionresult.Depth = contacts[i].depth; collisionresult.Normal = new Vector3(contacts[i].normal.X, contacts[i].normal.Y, contacts[i].normal.Z); lock (m_contactResults) m_contactResults.Add(collisionresult); } } } }
public override void Result(ContactResult point) { base.Result(point); OnResult?.Invoke((BaseMissionObjectController)point.Shape1.GetBody().GetUserData(), (BaseMissionObjectController)point.Shape2.GetBody().GetUserData()); }
private ContactResult[] ObjectIntersection(Vector3 rayStart, Vector3 rayEnd, bool includePhysical, bool includeNonPhysical, bool includePhantom) { Ray ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart)); List<ContactResult> contacts = new List<ContactResult>(); Vector3 ab = rayEnd - rayStart; World.ForEachSOG(delegate(SceneObjectGroup group) { if (m_host.ParentGroup == group) return; if (group.IsAttachment) return; if (group.RootPart.PhysActor == null) { if (!includePhantom) return; } else { if (group.RootPart.PhysActor.IsPhysical) { if (!includePhysical) return; } else { if (!includeNonPhysical) return; } } // Find the radius ouside of which we don't even need to hit test float minX; float maxX; float minY; float maxY; float minZ; float maxZ; float radius = 0.0f; group.GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ); if (Math.Abs(minX) > radius) radius = Math.Abs(minX); if (Math.Abs(minY) > radius) radius = Math.Abs(minY); if (Math.Abs(minZ) > radius) radius = Math.Abs(minZ); if (Math.Abs(maxX) > radius) radius = Math.Abs(maxX); if (Math.Abs(maxY) > radius) radius = Math.Abs(maxY); if (Math.Abs(maxZ) > radius) radius = Math.Abs(maxZ); radius = radius*1.413f; Vector3 ac = group.AbsolutePosition - rayStart; // Vector3 bc = group.AbsolutePosition - rayEnd; double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd)); // Too far off ray, don't bother if (d > radius) return; // Behind ray, drop double d2 = Vector3.Dot(Vector3.Negate(ab), ac); if (d2 > 0) return; ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart)); EntityIntersection intersection = group.TestIntersection(ray, true, false); // Miss. if (!intersection.HitTF) return; Vector3 b1 = group.AbsolutePosition + new Vector3(minX, minY, minZ); Vector3 b2 = group.AbsolutePosition + new Vector3(maxX, maxY, maxZ); //m_log.DebugFormat("[LLCASTRAY]: min<{0},{1},{2}>, max<{3},{4},{5}> = hitp<{6},{7},{8}>", b1.X,b1.Y,b1.Z,b2.X,b2.Y,b2.Z,intersection.ipoint.X,intersection.ipoint.Y,intersection.ipoint.Z); if (!(intersection.ipoint.X >= b1.X && intersection.ipoint.X <= b2.X && intersection.ipoint.Y >= b1.Y && intersection.ipoint.Y <= b2.Y && intersection.ipoint.Z >= b1.Z && intersection.ipoint.Z <= b2.Z)) return; ContactResult result = new ContactResult (); result.ConsumerID = group.LocalId; result.Depth = intersection.distance; result.Normal = intersection.normal; result.Pos = intersection.ipoint; contacts.Add(result); }); return contacts.ToArray(); }
public override void Result(ContactResult point) { this.OnResult?.Invoke(point); base.Result(point); }
// This is the standard Near. Uses space AABBs to speed up detection. private void near(IntPtr space, IntPtr g1, IntPtr g2) { //Don't test against heightfield Geom, or you'll be sorry! // Exclude heightfield geom if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) { return; } if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass || d.GeomGetClass(g2) == d.GeomClassID.HeightfieldClass) { return; } // Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms. if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2)) { if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) { return; } // Separating static prim geometry spaces. // We'll be calling near recursivly if one // of them is a space to find all of the // contact points in the space try { d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback); } catch (AccessViolationException) { MainConsole.Instance.Warn("[PHYSICS]: Unable to collide test a space"); return; } return; } if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) { return; } int count = 0; try { if (g1 == g2) { return; // Can't collide with yourself } count = d.CollidePtr(g1, g2, (contactsPerCollision & 0xffff), ContactgeomsArray, d.ContactGeom.unmanagedSizeOf); } catch (SEHException) { MainConsole.Instance.Error( "[PHYSICS]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim."); } catch (Exception e) { MainConsole.Instance.WarnFormat("[PHYSICS]: Unable to collide test an object: {0}", e); return; } PhysicsActor p1 = null; if (g1 != IntPtr.Zero) { m_scene.actor_name_map.TryGetValue(g1, out p1); } // Loop over contacts, build results. d.ContactGeom curContact = new d.ContactGeom(); for (int i = 0; i < count; i++) { if (!GetCurContactGeom(i, ref curContact)) { break; } if (p1 != null) { if (p1 is AuroraODEPrim) { ContactResult collisionresult = new ContactResult { ConsumerID = ((AuroraODEPrim)p1).LocalID, Pos = new Vector3(curContact.pos.X, curContact.pos.Y, curContact.pos.Z), Depth = curContact.depth, Normal = new Vector3(curContact.normal.X, curContact.normal.Y, curContact.normal.Z) }; lock (m_contactResults) m_contactResults.Add(collisionresult); } } } }
public override void Result(ContactResult point) { base.Result(point); }
private ContactResult[] ObjectIntersection(Vector3 rayStart, Vector3 rayEnd, bool includePhysical, bool includeNonPhysical, bool includePhantom, int max) { List<ContactResult> contacts = World.PhysicsScene.RaycastWorld(rayStart, Vector3.Normalize(rayEnd - rayStart), Vector3.Distance(rayEnd, rayStart), max); for (int i = 0; i < contacts.Count; i++) { ISceneEntity grp = World.GetGroupByPrim(contacts[i].ConsumerID); if(grp == null || (!includePhysical && grp.RootChild.PhysActor.IsPhysical) || (!includeNonPhysical && !grp.RootChild.PhysActor.IsPhysical)) contacts.RemoveAt(i--); } if (includePhantom) { Ray ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart)); Vector3 ab = rayEnd - rayStart; ISceneEntity[] objlist = World.Entities.GetEntities(); foreach (ISceneEntity group in objlist) { if (m_host.ParentEntity == group) continue; if (group.IsAttachment) continue; if (group.RootChild.PhysActor != null) continue; // Find the radius ouside of which we don't even need to hit test float minX; float maxX; float minY; float maxY; float minZ; float maxZ; float radius = 0.0f; group.GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ); if (Math.Abs(minX) > radius) radius = Math.Abs(minX); if (Math.Abs(minY) > radius) radius = Math.Abs(minY); if (Math.Abs(minZ) > radius) radius = Math.Abs(minZ); if (Math.Abs(maxX) > radius) radius = Math.Abs(maxX); if (Math.Abs(maxY) > radius) radius = Math.Abs(maxY); if (Math.Abs(maxZ) > radius) radius = Math.Abs(maxZ); radius = radius * 1.413f; Vector3 ac = group.AbsolutePosition - rayStart; // Vector3 bc = group.AbsolutePosition - rayEnd; double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd)); // Too far off ray, don't bother if (d > radius) continue; // Behind ray, drop double d2 = Vector3.Dot(Vector3.Negate(ab), ac); if (d2 > 0) continue; ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart)); EntityIntersection intersection = group.TestIntersection(ray, true, false); // Miss. if (!intersection.HitTF) continue; Vector3 b1 = new Vector3(minX, minY, minZ); Vector3 b2 = new Vector3(maxX, maxY, maxZ); //m_log.DebugFormat("[LLCASTRAY]: min<{0},{1},{2}>, max<{3},{4},{5}> = hitp<{6},{7},{8}>", b1.X,b1.Y,b1.Z,b2.X,b2.Y,b2.Z,intersection.ipoint.X,intersection.ipoint.Y,intersection.ipoint.Z); if (!(intersection.ipoint.X >= b1.X && intersection.ipoint.X <= b2.X && intersection.ipoint.Y >= b1.Y && intersection.ipoint.Y <= b2.Y && intersection.ipoint.Z >= b1.Z && intersection.ipoint.Z <= b2.Z)) continue; ContactResult result = new ContactResult(); result.ConsumerID = group.LocalId; result.Depth = intersection.distance; result.Normal = intersection.normal; result.Pos = intersection.ipoint; contacts.Add(result); } } return contacts.ToArray(); }
/// <summary> /// Gets the result of a ContactType on a set of PhysicalAttributes. /// </summary> /// <param name="attackerPhysAttributes">The attacker's set of PhysicalAttributes.</param> /// <param name="contactType">The ContactType performed.</param> /// <param name="contactProperty">The ContactProperty of the contact.</param> /// <param name="victimPaybacks">The victim's set of Paybacks to test against.</param> /// <param name="attackerContactExceptions">The attacker's contact exceptions; the set PhysicalAttributes to ignore.</param> /// <returns>A ContactResultInfo of the interaction.</returns> public static ContactResultInfo GetContactResult(IList <PhysicalAttributes> attackerPhysAttributes, ContactTypes contactType, ContactProperties contactProperty, IList <PaybackHolder> victimPaybacks, params PhysicalAttributes[] attackerContactExceptions) { //Return the default value if (victimPaybacks == null || victimPaybacks.Count == 0) { return(ContactResultInfo.Default); } /*0. Initialize a list of Paybacks, called PaybackList * 1. Go through all of the Victim's Paybacks * 2. Check if the Payback's PaybackContacts contains the ContactType of the attack * 3a. If so, check if the Attacker has any ContactExceptions for the Payback's PhysAttribute * 4a. If so, ignore it and continue * 4b. If not, check if the Payback covers any of the attack's ContactProperties * 5a. If so, check if the Attacker has the same PhysAttribute as the Payback's * 6a. If so, examine the SamePhysAttrResult and go to 7a * 6b. If not, examine the PaybackContactResult and go to 7a * 7a. If the ContactResult is a Failure, return that Payback value * 7b. If the ContactResult is a Success, ignore it and continue * 7c. If the ContactResult is a PartialSuccess, add it to PaybackList and continue * 4c. If not, ignore it and continue * 3b. If not, continue */ //The Paybacks that will be combined List <PaybackHolder> combinedPaybacks = new List <PaybackHolder>(); //Look through the Paybacks for (int i = 0; i < victimPaybacks.Count; i++) { PaybackHolder payback = victimPaybacks[i]; //Check if the Payback covers this ContactType if (payback.PaybackContacts != null && payback.PaybackContacts.Contains(contactType) == true) { //If there are contact exceptions for this PhysicalAttribute, ignore this Payback if (attackerContactExceptions.Contains(payback.PhysAttribute) == true) { continue; } //Check if the Payback covers the ContactProperty if (payback.ContactProperties != null && payback.ContactProperties.Contains(contactProperty) == false) { continue; } ContactResult contactResult = payback.PaybackContactResult; //Check if the Attacker has the PhysicalAttribute the Payback is associated with, and adjust the ContactResult if so if (attackerPhysAttributes.Contains(payback.PhysAttribute) == true) { contactResult = payback.SamePhysAttrResult; } //If a Failure, use this Payback if (contactResult == ContactResult.Failure) { return(new ContactResultInfo(payback, contactResult)); } //If a PartialSuccess, add it to the list else if (contactResult == ContactResult.PartialSuccess) { combinedPaybacks.Add(payback); } } } //Combine all the Paybacks in the list PaybackHolder finalPayback = PaybackHolder.CombinePaybacks(combinedPaybacks); return(new ContactResultInfo(finalPayback, finalPayback.PaybackContactResult)); }
private ContactResult? GroundIntersection(Vector3 rayStart, Vector3 rayEnd) { double[,] heightfield = World.Heightmap.GetDoubles(); List<ContactResult> contacts = new List<ContactResult>(); double min = 2048.0; double max = 0.0; // Find the min and max of the heightfield for (int x = 0 ; x < World.Heightmap.Width ; x++) { for (int y = 0 ; y < World.Heightmap.Height ; y++) { if (heightfield[x, y] > max) max = heightfield[x, y]; if (heightfield[x, y] < min) min = heightfield[x, y]; } } // A ray extends past rayEnd, but doesn't go back before // rayStart. If the start is above the highest point of the ground // and the ray goes up, we can't hit the ground. Ever. if (rayStart.Z > max && rayEnd.Z >= rayStart.Z) return null; // Same for going down if (rayStart.Z < min && rayEnd.Z <= rayStart.Z) return null; List<Tri> trilist = new List<Tri>(); // Create our triangle list for (int x = 1 ; x < World.Heightmap.Width ; x++) { for (int y = 1 ; y < World.Heightmap.Height ; y++) { Tri t1 = new Tri(); Tri t2 = new Tri(); Vector3 p1 = new Vector3(x-1, y-1, (float)heightfield[x-1, y-1]); Vector3 p2 = new Vector3(x, y-1, (float)heightfield[x, y-1]); Vector3 p3 = new Vector3(x, y, (float)heightfield[x, y]); Vector3 p4 = new Vector3(x-1, y, (float)heightfield[x-1, y]); t1.p1 = p1; t1.p2 = p2; t1.p3 = p3; t2.p1 = p3; t2.p2 = p4; t2.p3 = p1; trilist.Add(t1); trilist.Add(t2); } } // Ray direction Vector3 rayDirection = rayEnd - rayStart; foreach (Tri t in trilist) { // Compute triangle plane normal and edges Vector3 u = t.p2 - t.p1; Vector3 v = t.p3 - t.p1; Vector3 n = Vector3.Cross(u, v); if (n == Vector3.Zero) continue; Vector3 w0 = rayStart - t.p1; double a = -Vector3.Dot(n, w0); double b = Vector3.Dot(n, rayDirection); // Not intersecting the plane, or in plane (same thing) // Ignoring this MAY cause the ground to not be detected // sometimes if (Math.Abs(b) < 0.000001) continue; double r = a / b; // ray points away from plane if (r < 0.0) continue; Vector3 ip = rayStart + Vector3.Multiply(rayDirection, (float)r); float uu = Vector3.Dot(u, u); float uv = Vector3.Dot(u, v); float vv = Vector3.Dot(v, v); Vector3 w = ip - t.p1; float wu = Vector3.Dot(w, u); float wv = Vector3.Dot(w, v); float d = uv * uv - uu * vv; float cs = (uv * wv - vv * wu) / d; if (cs < 0 || cs > 1.0) continue; float ct = (uv * wu - uu * wv) / d; if (ct < 0 || (cs + ct) > 1.0) continue; // Add contact point ContactResult result = new ContactResult (); result.ConsumerID = 0; result.Depth = Vector3.Distance(rayStart, ip); result.Normal = n; result.Pos = ip; contacts.Add(result); } if (contacts.Count == 0) return null; contacts.Sort(delegate(ContactResult a, ContactResult b) { return (int)(a.Depth - b.Depth); }); return contacts[0]; }
public override void Result(ContactResult point) { base.Result(point); onResult?.Invoke(point); }
// This is the standard Near. Uses space AABBs to speed up detection. private void near(IntPtr space, IntPtr g1, IntPtr g2) { //Don't test against heightfield Geom, or you'll be sorry! /* terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc Stacktrace: at (wrapper managed-to-native) Ode.NET.d.Collide (intptr,intptr,int,Ode.NET.d/ContactGeom[],int) <0x00004> at (wrapper managed-to-native) Ode.NET.d.Collide (intptr,intptr,int,Ode.NET.d/ContactGeom[],int) <0xffffffff> at OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.near (intptr,intptr,intptr) <0x00280> at (wrapper native-to-managed) OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.near (intptr,intptr,intptr) <0xfff fffff> at (wrapper managed-to-native) Ode.NET.d.SpaceCollide2 (intptr,intptr,intptr,Ode.NET.d/NearCallback) <0x00004> at (wrapper managed-to-native) Ode.NET.d.SpaceCollide2 (intptr,intptr,intptr,Ode.NET.d/NearCallback) <0xffffffff> at OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.RayCast (OpenSim.Region.Physics.OdePlugin.ODERayCastRequest) < 0x00114> at OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.ProcessQueuedRequests () <0x000eb> at OpenSim.Region.Physics.OdePlugin.OdeScene.Simulate (single) <0x017e6> at OpenSim.Region.Framework.Scenes.SceneGraph.UpdatePhysics (double) <0x00042> at OpenSim.Region.Framework.Scenes.Scene.Update () <0x0039e> at OpenSim.Region.Framework.Scenes.Scene.Heartbeat (object) <0x00019> at (wrapper runtime-invoke) object.runtime_invoke_void__this___object (object,intptr,intptr,intptr) <0xffffffff> Native stacktrace: mono [0x80d2a42] [0xb7f5840c] /lib/i686/cmov/libc.so.6(abort+0x188) [0xb7d1a018] /usr/lib/libstdc++.so.6(_ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x158) [0xb45fc988] /usr/lib/libstdc++.so.6 [0xb45fa865] /usr/lib/libstdc++.so.6 [0xb45fa8a2] /usr/lib/libstdc++.so.6 [0xb45fa9da] /usr/lib/libstdc++.so.6(_Znwj+0x83) [0xb45fb033] /usr/lib/libstdc++.so.6(_Znaj+0x1d) [0xb45fb11d] libode.so(_ZN13dxHeightfield23dCollideHeightfieldZoneEiiiiP6dxGeomiiP12dContactGeomi+0xd04) [0xb46678e4] libode.so(_Z19dCollideHeightfieldP6dxGeomS0_iP12dContactGeomi+0x54b) [0xb466832b] libode.so(dCollide+0x102) [0xb46571b2] [0x95cfdec9] [0x8ea07fe1] [0xab260146] libode.so [0xb465a5c4] libode.so(_ZN11dxHashSpace8collide2EPvP6dxGeomPFvS0_S2_S2_E+0x75) [0xb465bcf5] libode.so(dSpaceCollide2+0x177) [0xb465ac67] [0x95cf978e] [0x8ea07945] [0x95cf2bbc] [0xab2787e7] [0xab419fb3] [0xab416657] [0xab415bda] [0xb609b08e] mono(mono_runtime_delegate_invoke+0x34) [0x8192534] mono [0x81a2f0f] mono [0x81d28b6] mono [0x81ea2c6] /lib/i686/cmov/libpthread.so.0 [0xb7e744c0] /lib/i686/cmov/libc.so.6(clone+0x5e) [0xb7dcd6de] */ // Exclude heightfield geom if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) return; if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass || d.GeomGetClass(g2) == d.GeomClassID.HeightfieldClass) return; // Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms. if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2)) { if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) return; // Separating static prim geometry spaces. // We'll be calling near recursivly if one // of them is a space to find all of the // contact points in the space try { d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback); } catch (AccessViolationException) { m_log.Warn("[PHYSICS]: Unable to collide test a space"); return; } //Colliding a space or a geom with a space or a geom. so drill down //Collide all geoms in each space.. //if (d.GeomIsSpace(g1)) d.SpaceCollide(g1, IntPtr.Zero, nearCallback); //if (d.GeomIsSpace(g2)) d.SpaceCollide(g2, IntPtr.Zero, nearCallback); return; } if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) return; int count = 0; try { if (g1 == g2) return; // Can't collide with yourself lock (contacts) { count = d.Collide(g1, g2, contacts.GetLength(0), contacts, d.ContactGeom.SizeOf); } } catch (SEHException) { m_log.Error("[PHYSICS]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim."); } catch (Exception e) { m_log.WarnFormat("[PHYSICS]: Unable to collide test an object: {0}", e.Message); return; } PhysicsActor p1 = null; PhysicsActor p2 = null; if (g1 != IntPtr.Zero) m_scene.actor_name_map.TryGetValue(g1, out p1); if (g2 != IntPtr.Zero) m_scene.actor_name_map.TryGetValue(g1, out p2); // Loop over contacts, build results. for (int i = 0; i < count; i++) { if (p1 != null) { if (p1 is OdePrim) { ContactResult collisionresult = new ContactResult(); collisionresult.ConsumerID = ((OdePrim)p1).m_localID; collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z); collisionresult.Depth = contacts[i].depth; lock (m_contactResults) m_contactResults.Add(collisionresult); } } if (p2 != null) { if (p2 is OdePrim) { ContactResult collisionresult = new ContactResult(); collisionresult.ConsumerID = ((OdePrim)p2).m_localID; collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z); collisionresult.Depth = contacts[i].depth; lock (m_contactResults) m_contactResults.Add(collisionresult); } } } }
public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) { Vector3 dir = new Vector3((float) (end - start).x, (float) (end - start).y, (float) (end - start).z); Vector3 startvector = new Vector3((float) start.x, (float) start.y, (float) start.z); Vector3 endvector = new Vector3((float) end.x, (float) end.y, (float) end.z); int count = 0; int detectPhantom = 0; int dataFlags = 0; int rejectTypes = 0; for (int i = 0; i < options.Length; i += 2) { if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS) { count = options.GetLSLIntegerItem(i + 1); } else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM) { detectPhantom = options.GetLSLIntegerItem(i + 1); } else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS) { dataFlags = options.GetLSLIntegerItem(i + 1); } else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES) { rejectTypes = options.GetLSLIntegerItem(i + 1); } } LSL_List list = new LSL_List(); List<ContactResult> results = World.PhysicsScene.RaycastWorld(startvector, dir, dir.Length(), count); double distance = Util.GetDistanceTo(startvector, endvector); if (distance == 0) distance = 0.001; Vector3 posToCheck = startvector; ITerrainChannel channel = World.RequestModuleInterface<ITerrainChannel>(); List<IScenePresence> presences = new List<IScenePresence>(World.Entities.GetPresences(startvector, (float) distance)); bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND); bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS); bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL); bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); for (float i = 0; i <= distance; i += 0.1f) { posToCheck = startvector + (dir*(i/(float) distance)); float groundHeight = channel[(int) (posToCheck.X + startvector.X), (int) (posToCheck.Y + startvector.Y)]; if (checkTerrain && groundHeight > posToCheck.Z) { ContactResult result = new ContactResult { ConsumerID = 0, Depth = 0, Normal = Vector3.Zero, Pos = posToCheck }; results.Add(result); checkTerrain = false; } if (checkAgents) { for (int presenceCount = 0; presenceCount < presences.Count; presenceCount++) { IScenePresence sp = presences[presenceCount]; if (sp.AbsolutePosition.ApproxEquals(posToCheck, sp.PhysicsActor.Size.X)) { ContactResult result = new ContactResult { ConsumerID = sp.LocalId, Depth = 0, Normal = Vector3.Zero, Pos = posToCheck }; results.Add(result); presences.RemoveAt(presenceCount); if (presenceCount > 0) presenceCount--; //Reset its position since we removed this one } } } } int refcount = 0; List<ContactResult> newResults = new List<ContactResult>(); foreach (ContactResult result in results) { foreach (ContactResult r in newResults) if (r.ConsumerID == result.ConsumerID) newResults.Add(result); } castRaySort(startvector, ref newResults); foreach (ContactResult result in newResults) { if ((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND && result.ConsumerID == 0) continue; IEntity entity = World.GetSceneObjectPart(result.ConsumerID); if (entity == null && (rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) != ScriptBaseClass.RC_REJECT_AGENTS) entity = World.GetScenePresence(result.ConsumerID); //Only check if we should be looking for agents if (entity == null) { list.Add(UUID.Zero); if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) list.Add(0); list.Add(result.Pos); if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) list.Add(result.Normal); refcount++; continue; //Can't find it, so add UUID.Zero } /*if (detectPhantom == 0 && intersection.obj is ISceneChildEntity && ((ISceneChildEntity)intersection.obj).PhysActor == null) continue;*/ //Can't do this ATM, physics engine knows only of non phantom objects if (entity is ISceneChildEntity && ((ISceneChildEntity) entity).PhysActor != null && ((ISceneChildEntity) entity).PhysActor.IsPhysical) { if (!checkPhysical) continue; } else if (entity is ISceneChildEntity) if (!checkNonPhysical) continue; refcount++; if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY && entity is ISceneChildEntity) list.Add(((ISceneChildEntity) entity).ParentEntity.UUID); else list.Add(entity.UUID); if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) if (entity is ISceneChildEntity) list.Add(entity.LinkNum); else list.Add(0); list.Add(result.Pos); if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) list.Add(result.Normal); } list.Add(refcount); //The status code, either the # of contacts, RCERR_SIM_PERF_LOW, or RCERR_CAST_TIME_EXCEEDED return list; }
public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) { m_host.AddScriptLPS(1); Vector3 dir = new Vector3((float)(end-start).x, (float)(end-start).y, (float)(end-start).z); Vector3 startvector = new Vector3((float)start.x, (float)start.y, (float)start.z); Vector3 endvector = new Vector3((float)end.x, (float)end.y, (float)end.z); int count = 0; // int detectPhantom = 0; int dataFlags = 0; int rejectTypes = 0; for (int i = 0; i < options.Length; i += 2) { if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS) { count = options.GetLSLIntegerItem(i + 1); } // else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM) // { // detectPhantom = options.GetLSLIntegerItem(i + 1); // } else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS) { dataFlags = options.GetLSLIntegerItem(i + 1); } else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES) { rejectTypes = options.GetLSLIntegerItem(i + 1); } } LSL_List list = new LSL_List(); List<ContactResult> results = World.PhysicsScene.RaycastWorld(startvector, dir, dir.Length(), count); double distance = Util.GetDistanceTo(startvector, endvector); if (distance == 0) distance = 0.001; Vector3 posToCheck = startvector; ITerrainChannel channel = World.RequestModuleInterface<ITerrainChannel>(); bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND); bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS); bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL); bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); for (float i = 0; i <= distance; i += 0.1f) { posToCheck = startvector + (dir * (i / (float)distance)); if (checkTerrain && channel[(int)(posToCheck.X + startvector.X), (int)(posToCheck.Y + startvector.Y)] < posToCheck.Z) { ContactResult result = new ContactResult(); result.ConsumerID = 0; result.Depth = 0; result.Normal = Vector3.Zero; result.Pos = posToCheck; results.Add(result); checkTerrain = false; } if (checkAgents) { World.ForEachRootScenePresence(delegate(ScenePresence sp) { if (sp.AbsolutePosition.ApproxEquals(posToCheck, sp.PhysicsActor.Size.X)) { ContactResult result = new ContactResult (); result.ConsumerID = sp.LocalId; result.Depth = 0; result.Normal = Vector3.Zero; result.Pos = posToCheck; results.Add(result); } }); } } int refcount = 0; foreach (ContactResult result in results) { if ((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND && result.ConsumerID == 0) continue; ISceneEntity entity = World.GetSceneObjectPart(result.ConsumerID); if (entity == null && (rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) != ScriptBaseClass.RC_REJECT_AGENTS) entity = World.GetScenePresence(result.ConsumerID); //Only check if we should be looking for agents if (entity == null) { list.Add(UUID.Zero); if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) list.Add(0); list.Add(result.Pos); if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) list.Add(result.Normal); continue; //Can't find it, so add UUID.Zero } /*if (detectPhantom == 0 && intersection.obj is ISceneChildEntity && ((ISceneChildEntity)intersection.obj).PhysActor == null) continue;*/ //Can't do this ATM, physics engine knows only of non phantom objects if (entity is SceneObjectPart) { PhysicsActor pa = ((SceneObjectPart)entity).PhysActor; if (pa != null && pa.IsPhysical) { if (!checkPhysical) continue; } else { if (!checkNonPhysical) continue; } } refcount++; if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY && entity is SceneObjectPart) list.Add(((SceneObjectPart)entity).ParentGroup.UUID); else list.Add(entity.UUID); if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) { if (entity is SceneObjectPart) list.Add(((SceneObjectPart)entity).LinkNum); else list.Add(0); } list.Add(result.Pos); if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) list.Add(result.Normal); } list.Add(refcount); //The status code, either the # of contacts, RCERR_SIM_PERF_LOW, or RCERR_CAST_TIME_EXCEEDED return list; }
// This is the standard Near. g2 is the ray private void near(IntPtr space, IntPtr g1, IntPtr g2) { //Don't test against heightfield Geom, or you'll be sorry! // Exclude heightfield geom if (g1 == IntPtr.Zero || g1 == g2) return; if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass) return; // Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms. if (d.GeomIsSpace(g1)) { try { d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback); } catch (Exception e) { m_log.WarnFormat("[PHYSICS Ray]: Unable to Space collide test an object: {0}", e.Message); } return; } int count = 0; try { count = d.CollidePtr(g1, g2, ColisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf); } catch (SEHException) { m_log.Error("[PHYSICS Ray]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim."); } catch (Exception e) { m_log.WarnFormat("[PHYSICS Ray]: Unable to collide test an object: {0}", e.Message); return; } if (count == 0) return; PhysicsActor p1 = null; if (g1 != IntPtr.Zero) m_scene.actor_name_map.TryGetValue(g1, out p1); d.ContactGeom curcontact = new d.ContactGeom(); // Loop over contacts, build results. for (int i = 0; i < count; i++) { if (!GetCurContactGeom(i, ref curcontact)) break; if (p1 != null) { if (p1 is OdePrim) { ContactResult collisionresult = new ContactResult(); collisionresult.ConsumerID = ((OdePrim)p1).m_localID; collisionresult.Pos = new Vector3(curcontact.pos.X, curcontact.pos.Y, curcontact.pos.Z); collisionresult.Depth = curcontact.depth; collisionresult.Normal = new Vector3(curcontact.normal.X, curcontact.normal.Y, curcontact.normal.Z); lock (m_contactResults) m_contactResults.Add(collisionresult); } } } }
// This is the standard Near. Uses space AABBs to speed up detection. private void near(IntPtr space, IntPtr g1, IntPtr g2) { //Don't test against heightfield Geom, or you'll be sorry! /* * terminate called after throwing an instance of 'std::bad_alloc' * what(): std::bad_alloc * Stacktrace: * * at (wrapper managed-to-native) Ode.NET.d.Collide (intptr,intptr,int,Ode.NET.d/ContactGeom[],int) <0x00004> * at (wrapper managed-to-native) Ode.NET.d.Collide (intptr,intptr,int,Ode.NET.d/ContactGeom[],int) <0xffffffff> * at OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.near (intptr,intptr,intptr) <0x00280> * at (wrapper native-to-managed) OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.near (intptr,intptr,intptr) <0xfff * fffff> * at (wrapper managed-to-native) Ode.NET.d.SpaceCollide2 (intptr,intptr,intptr,Ode.NET.d/NearCallback) <0x00004> * at (wrapper managed-to-native) Ode.NET.d.SpaceCollide2 (intptr,intptr,intptr,Ode.NET.d/NearCallback) <0xffffffff> * at OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.RayCast (OpenSim.Region.Physics.OdePlugin.ODERayCastRequest) < * 0x00114> * at OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.ProcessQueuedRequests () <0x000eb> * at OpenSim.Region.Physics.OdePlugin.OdeScene.Simulate (single) <0x017e6> * at OpenSim.Region.Framework.Scenes.SceneGraph.UpdatePhysics (double) <0x00042> * at OpenSim.Region.Framework.Scenes.Scene.Update () <0x0039e> * at OpenSim.Region.Framework.Scenes.Scene.Heartbeat (object) <0x00019> * at (wrapper runtime-invoke) object.runtime_invoke_void__this___object (object,intptr,intptr,intptr) <0xffffffff> * * Native stacktrace: * * mono [0x80d2a42] * [0xb7f5840c] * /lib/i686/cmov/libc.so.6(abort+0x188) [0xb7d1a018] * /usr/lib/libstdc++.so.6(_ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x158) [0xb45fc988] * /usr/lib/libstdc++.so.6 [0xb45fa865] * /usr/lib/libstdc++.so.6 [0xb45fa8a2] * /usr/lib/libstdc++.so.6 [0xb45fa9da] * /usr/lib/libstdc++.so.6(_Znwj+0x83) [0xb45fb033] * /usr/lib/libstdc++.so.6(_Znaj+0x1d) [0xb45fb11d] * libode.so(_ZN13dxHeightfield23dCollideHeightfieldZoneEiiiiP6dxGeomiiP12dContactGeomi+0xd04) [0xb46678e4] * libode.so(_Z19dCollideHeightfieldP6dxGeomS0_iP12dContactGeomi+0x54b) [0xb466832b] * libode.so(dCollide+0x102) [0xb46571b2] * [0x95cfdec9] * [0x8ea07fe1] * [0xab260146] * libode.so [0xb465a5c4] * libode.so(_ZN11dxHashSpace8collide2EPvP6dxGeomPFvS0_S2_S2_E+0x75) [0xb465bcf5] * libode.so(dSpaceCollide2+0x177) [0xb465ac67] * [0x95cf978e] * [0x8ea07945] * [0x95cf2bbc] * [0xab2787e7] * [0xab419fb3] * [0xab416657] * [0xab415bda] * [0xb609b08e] * mono(mono_runtime_delegate_invoke+0x34) [0x8192534] * mono [0x81a2f0f] * mono [0x81d28b6] * mono [0x81ea2c6] * /lib/i686/cmov/libpthread.so.0 [0xb7e744c0] * /lib/i686/cmov/libc.so.6(clone+0x5e) [0xb7dcd6de] */ // Exclude heightfield geom if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) { return; } if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass || d.GeomGetClass(g2) == d.GeomClassID.HeightfieldClass) { return; } // Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms. if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2)) { if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) { return; } // Separating static prim geometry spaces. // We'll be calling near recursivly if one // of them is a space to find all of the // contact points in the space try { d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback); } catch (AccessViolationException) { MainConsole.Instance.Warn("[PHYSICS]: Unable to collide test a space"); return; } //Colliding a space or a geom with a space or a geom. so drill down //Collide all geoms in each space.. //if (d.GeomIsSpace(g1)) d.SpaceCollide(g1, IntPtr.Zero, nearCallback); //if (d.GeomIsSpace(g2)) d.SpaceCollide(g2, IntPtr.Zero, nearCallback); return; } if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) { return; } int count = 0; try { if (g1 == g2) { return; // Can't collide with yourself } count = d.CollidePtr(g1, g2, (contactsPerCollision & 0xffff), ContactgeomsArray, d.ContactGeom.unmanagedSizeOf); } catch (SEHException) { MainConsole.Instance.Error( "[PHYSICS]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim."); } catch (Exception e) { MainConsole.Instance.WarnFormat("[PHYSICS]: Unable to collide test an object: {0}", e); return; } PhysicsActor p1 = null; if (g1 != IntPtr.Zero) { m_scene.actor_name_map.TryGetValue(g1, out p1); } // Loop over contacts, build results. d.ContactGeom curContact = new d.ContactGeom(); for (int i = 0; i < count; i++) { if (!GetCurContactGeom(i, ref curContact)) { break; } if (p1 != null) { if (p1 is AuroraODEPrim) { ContactResult collisionresult = new ContactResult { ConsumerID = ((AuroraODEPrim)p1).LocalID, Pos = new Vector3(curContact.pos.X, curContact.pos.Y, curContact.pos.Z), Depth = curContact.depth, Normal = new Vector3(curContact.normal.X, curContact.normal.Y, curContact.normal.Z) }; lock (m_contactResults) m_contactResults.Add(collisionresult); } } } }
public static InteractionResult GetDamageInteractionOld(InteractionParamHolder interactionParam) { InteractionResult finalInteractionResult = new InteractionResult(); BattleEntity attacker = interactionParam.Attacker; BattleEntity victim = interactionParam.Victim; ContactTypes contactType = interactionParam.ContactType; Elements element = interactionParam.DamagingElement; StatusChanceHolder[] statuses = interactionParam.Statuses; int damage = interactionParam.Damage; bool piercing = interactionParam.Piercing; //Get contact results ContactResultInfo contactResultInfo = victim.EntityProperties.GetContactResult(attacker, contactType); ContactResult contactResult = contactResultInfo.ContactResult; //Retrieve an overridden type of Elemental damage to inflict based on the Victim's PhysicalAttributes //(Ex. The Ice Power Badge only deals Ice damage to Fiery entities) ElementOverrideHolder newElement = attacker.EntityProperties.GetTotalElementOverride(victim); if (newElement.Element != Elements.Invalid) { //Add the number of element overrides to the damage if the element used already exists as an override and the victim has a Weakness //to the Element. This allows Badges such as Ice Power to deal more damage if used in conjunction with attacks //that deal the same type of damage (Ex. Ice Power and Ice Smash deal 2 additional damage total rather than 1). //If any new knowledge is discovered to improve this, this will be changed //Ice Power is the only Badge of its kind across the first two PM games that does anything like this if (element == newElement.Element && victim.EntityProperties.HasWeakness(element) == true) { damage += newElement.OverrideCount; } element = newElement.Element; } /*Get the total damage dealt to the Victim. The amount of Full or Half Payback damage dealt to the Attacker * uses the resulting damage value from this because Payback uses the total damage that would be dealt to the Victim. * This occurs before factoring in elemental resistances/weaknesses from the Attacker*/ ElementDamageResultHolder victimElementDamage = GetElementalDamage(victim, element, damage); int unscaledVictimDamage = victimElementDamage.Damage; //Subtract damage reduction (P-Up, D-Down and P-Down, D-Up Badges) unscaledVictimDamage -= victim.BattleStats.DamageReduction; //Check if the attack hit. If not, then don't consider defensive actions bool attackHit = interactionParam.CantMiss == true ? true : attacker.AttemptHitEntity(victim); //Defense added from Damage Dodge Badges upon a successful Guard int damageDodgeDefense = 0; //Defensive actions take priority. If the attack didn't hit, don't check for defensive actions BattleGlobals.DefensiveActionHolder?victimDefenseData = null; if (attackHit == true) { victimDefenseData = victim.GetDefensiveActionResult(unscaledVictimDamage, statuses, interactionParam.DamageEffect); } if (victimDefenseData.HasValue == true) { unscaledVictimDamage = victimDefenseData.Value.Damage; statuses = victimDefenseData.Value.Statuses; //If the Defensive action dealt damage and the contact was direct //the Defensive action has caused a Failure for the Attacker (Ex. Superguarding) if ((contactType == ContactTypes.TopDirect || contactType == ContactTypes.SideDirect) && victimDefenseData.Value.ElementHolder.HasValue == true) { contactResult = ContactResult.Failure; } //Factor in the additional Guard defense for all DefensiveActions (for now, at least) damageDodgeDefense = victim.GetEquippedBadgeCount(BadgeGlobals.BadgeTypes.DamageDodge); } //Subtract Defense on non-piercing damage if (piercing == false) { int totalDefense = victim.BattleStats.TotalDefense + damageDodgeDefense; unscaledVictimDamage -= totalDefense; } int scaledVictimDamage = unscaledVictimDamage; //Factor in Double Pain for the Victim scaledVictimDamage *= (1 + victim.GetEquippedBadgeCount(BadgeGlobals.BadgeTypes.DoublePain)); //Factor in Last Stand for the Victim, if the Victim is in Danger or Peril if (victim.IsInDanger == true) { //PM rounds down, whereas TTYD rounds up. We're going with the latter //TTYD always ceilings the value (Ex. 3.2 turns to 4) int lastStandDivider = (1 + victim.GetEquippedBadgeCount(BadgeGlobals.BadgeTypes.LastStand)); scaledVictimDamage = (int)Math.Ceiling(scaledVictimDamage / (float)lastStandDivider); } /*If the Victim is Invincible, ignore all damage and Status Effects * If the Attacker is Invincible, ignore all Payback damage and Status Effects * * It won't ignore the Payback's effects automatically; that has to be done manually by adding * contact exceptions or something else*/ //Clamp Victim damage scaledVictimDamage = UtilityGlobals.Clamp(scaledVictimDamage, BattleGlobals.MinDamage, BattleGlobals.MaxDamage); #region Victim Damage Dealt //Calculating damage dealt to the Victim if (contactResult == ContactResult.Success || contactResult == ContactResult.PartialSuccess) { //Get the Status Effects to inflict on the Victim StatusChanceHolder[] victimInflictedStatuses = GetFilteredInflictedStatuses(victim, statuses); //Check if the Victim is Invincible. If so, ignore all damage and Status Effects if (victim.EntityProperties.GetAdditionalProperty <bool>(AdditionalProperty.Invincible) == true) { scaledVictimDamage = 0; victimElementDamage.InteractionResult = ElementInteractionResult.Damage; victimInflictedStatuses = null; } finalInteractionResult.VictimResult = new InteractionHolder(victim, scaledVictimDamage, element, victimElementDamage.InteractionResult, contactType, piercing, victimInflictedStatuses, attackHit, DamageEffects.None); } #endregion #region Attacker Damage Dealt //Calculating damage dealt to the Attacker if (contactResult == ContactResult.Failure || contactResult == ContactResult.PartialSuccess) { //The damage the Attacker dealt to the Victim int damageDealt = unscaledVictimDamage; PaybackHolder paybackHolder = contactResultInfo.Paybackholder; //Override the PaybackHolder with a Defensive Action's results, if any if (victimDefenseData.HasValue == true && victimDefenseData.Value.ElementHolder.HasValue == true) { damageDealt = victimDefenseData.Value.ElementHolder.Value.Damage; paybackHolder = new PaybackHolder(PaybackTypes.Constant, victimDefenseData.Value.ElementHolder.Value.Element, damageDealt); } //Get the damage done to the Attacker, factoring in Weaknesses/Resistances ElementDamageResultHolder attackerElementDamage = GetElementalDamage(attacker, paybackHolder.Element, damageDealt); //Get Payback damage - Payback damage is calculated after everything else, including Constant Payback. //However, it does NOT factor in Double Pain or any sort of Defense modifiers. int paybackDamage = paybackHolder.GetPaybackDamage(attackerElementDamage.Damage); //If Constant Payback, update the damage value to use the element if (paybackHolder.PaybackType == PaybackTypes.Constant) { paybackDamage = GetElementalDamage(attacker, paybackHolder.Element, paybackDamage).Damage; } //Clamp Attacker damage attackerElementDamage.Damage = UtilityGlobals.Clamp(paybackDamage, BattleGlobals.MinDamage, BattleGlobals.MaxDamage); //Get the Status Effects to inflict StatusChanceHolder[] attackerInflictedStatuses = GetFilteredInflictedStatuses(attacker, paybackHolder.StatusesInflicted); //Check if the Attacker is Invincible. If so, ignore all damage and Status Effects if (attacker.EntityProperties.GetAdditionalProperty <bool>(AdditionalProperty.Invincible) == true) { attackerElementDamage.Damage = 0; attackerElementDamage.InteractionResult = ElementInteractionResult.Damage; attackerInflictedStatuses = null; } finalInteractionResult.AttackerResult = new InteractionHolder(attacker, attackerElementDamage.Damage, paybackHolder.Element, attackerElementDamage.InteractionResult, ContactTypes.None, true, attackerInflictedStatuses, true, DamageEffects.None); } #endregion return(finalInteractionResult); }