void CalcBoundingPlanes(Vector3 u, out double minDot, out double maxDot) { double centerDot = Vector3Ex.Dot(u, Center); double AxisCdotU = Vector3Ex.Dot(CenterAxis, u); if (IsRightCylinderFlag) { double deltaDot = HalfHeight * Math.Abs(AxisCdotU) + Math.Sqrt(Square(RadiusA * RadiusA * Vector3Ex.Dot(AxisA, u)) + Square(RadiusB * RadiusB * Vector3Ex.Dot(AxisB, u))); minDot = centerDot - deltaDot; maxDot = centerDot + deltaDot; return; } double maxD, minD; // Handle top face Vector3 perp = TopNormal; perp *= u; double alpha = Vector3Ex.Dot(perp, AxisA) * RadiusA; double beta = Vector3Ex.Dot(perp, AxisB) * RadiusB; if (alpha == 0.0 && beta == 0.0) { // If u perpendicular to top face maxD = minD = TopPlaneCoef * Vector3Ex.Dot(u, TopNormal); } else { double solnX = -beta * RadiusA * RadiusA; double solnY = alpha * RadiusB * RadiusB; double ratio = Math.Sqrt(Square(alpha * RadiusB) + Square(beta * RadiusA)); solnX /= ratio; // Now solnX and solnY give point on cylinder to check solnY /= ratio; Vector3 trial = perp; // Be careful: reuse of Vector3 to avoid constructor overhead trial = Center; trial += AxisA * (solnX * RadiusA); trial += AxisB * (solnY * RadiusB); // This is what it was. LBB - trial.AddScaled( AxisB, solnY*RadiusB ); maxD = minD = Vector3Ex.Dot(trial, u) + (TopPlaneCoef - Vector3Ex.Dot(trial, TopNormal)) * AxisCdotU / Vector3Ex.Dot(CenterAxis, TopNormal); trial = Center; trial += AxisA * (-solnX * RadiusA); trial += AxisB * (-solnY * RadiusB); double newDot = Vector3Ex.Dot(trial, u) + (TopPlaneCoef - Vector3Ex.Dot(trial, TopNormal)) * AxisCdotU / Vector3Ex.Dot(CenterAxis, TopNormal); UpdateMinMax(newDot, minD, maxD); } // Handle bottom face perp = BottomNormal; perp *= u; alpha = Vector3Ex.Dot(perp, AxisA) * RadiusA; beta = Vector3Ex.Dot(perp, AxisB) * RadiusB; if (alpha == 0.0 && beta == 0.0) { // If u perpendicular to bottom face UpdateMinMax(BottomPlaneCoef * Vector3Ex.Dot(u, BottomNormal), minD, maxD); } else { double solnX = -beta * RadiusA * RadiusA; double solnY = alpha * RadiusB * RadiusB; double ratio = Math.Sqrt(Square(alpha * RadiusB) + Square(beta * RadiusA)); solnX /= ratio; // Now solnX and solnY give point on cylinder to check solnY /= ratio; Vector3 trial = Center; trial += AxisA * (solnX * RadiusA); trial += AxisB * (solnY * RadiusB); double newDot = Vector3Ex.Dot(trial, u) + (BottomPlaneCoef - Vector3Ex.Dot(trial, BottomNormal)) * AxisCdotU / Vector3Ex.Dot(CenterAxis, BottomNormal); UpdateMinMax(newDot, minD, maxD); trial = Center; trial += AxisA * (-solnX * RadiusA); trial += AxisB * (-solnY * RadiusB); newDot = Vector3Ex.Dot(trial, u) + (BottomPlaneCoef - Vector3Ex.Dot(trial, BottomNormal)) * AxisCdotU / Vector3Ex.Dot(CenterAxis, BottomNormal); UpdateMinMax(newDot, minD, maxD); } minDot = minD; maxDot = maxD; }
///<summary> /// Updates the time of impact for the pair. ///</summary> ///<param name="requester">Collidable requesting the update.</param> ///<param name="dt">Timestep duration.</param> public override void UpdateTimeOfImpact(Collidable requester, float dt) { var overlap = BroadPhaseOverlap; var meshMode = mobileMesh.entity == null ? PositionUpdateMode.Discrete : mobileMesh.entity.PositionUpdateMode; var convexMode = convex.entity == null ? PositionUpdateMode.Discrete : convex.entity.PositionUpdateMode; if ( (mobileMesh.IsActive || convex.IsActive) && //At least one has to be active. ( ( convexMode == PositionUpdateMode.Continuous && //If both are continuous, only do the process for A. meshMode == PositionUpdateMode.Continuous && overlap.entryA == requester ) || ( convexMode == PositionUpdateMode.Continuous ^ //If only one is continuous, then we must do it. meshMode == PositionUpdateMode.Continuous ) ) ) { //TODO: This system could be made more robust by using a similar region-based rejection of edges. //CCD events are awfully rare under normal circumstances, so this isn't usually an issue. //Only perform the test if the minimum radii are small enough relative to the size of the velocity. System.Numerics.Vector3 velocity; if (convexMode == PositionUpdateMode.Discrete) { //Convex is static for the purposes of CCD. Vector3Ex.Negate(ref mobileMesh.entity.linearVelocity, out velocity); } else if (meshMode == PositionUpdateMode.Discrete) { //Mesh is static for the purposes of CCD. velocity = convex.entity.linearVelocity; } else { //Both objects can move. Vector3Ex.Subtract(ref convex.entity.linearVelocity, ref mobileMesh.entity.linearVelocity, out velocity); } Vector3Ex.Multiply(ref velocity, dt, out velocity); float velocitySquared = velocity.LengthSquared(); var minimumRadius = convex.Shape.MinimumRadius * MotionSettings.CoreShapeScaling; timeOfImpact = 1; if (minimumRadius * minimumRadius < velocitySquared) { TriangleSidedness sidedness = mobileMesh.Shape.Sidedness; Matrix3x3 orientation; Matrix3x3.CreateFromQuaternion(ref mobileMesh.worldTransform.Orientation, out orientation); var triangle = PhysicsThreadResources.GetTriangle(); triangle.collisionMargin = 0; //Spherecast against all triangles to find the earliest time. for (int i = 0; i < MeshManifold.overlappedTriangles.Count; i++) { MeshBoundingBoxTreeData data = mobileMesh.Shape.TriangleMesh.Data; int triangleIndex = MeshManifold.overlappedTriangles.Elements[i]; data.GetTriangle(triangleIndex, out triangle.vA, out triangle.vB, out triangle.vC); Matrix3x3.Transform(ref triangle.vA, ref orientation, out triangle.vA); Matrix3x3.Transform(ref triangle.vB, ref orientation, out triangle.vB); Matrix3x3.Transform(ref triangle.vC, ref orientation, out triangle.vC); Vector3Ex.Add(ref triangle.vA, ref mobileMesh.worldTransform.Position, out triangle.vA); Vector3Ex.Add(ref triangle.vB, ref mobileMesh.worldTransform.Position, out triangle.vB); Vector3Ex.Add(ref triangle.vC, ref mobileMesh.worldTransform.Position, out triangle.vC); //Put the triangle into 'localish' space of the convex. Vector3Ex.Subtract(ref triangle.vA, ref convex.worldTransform.Position, out triangle.vA); Vector3Ex.Subtract(ref triangle.vB, ref convex.worldTransform.Position, out triangle.vB); Vector3Ex.Subtract(ref triangle.vC, ref convex.worldTransform.Position, out triangle.vC); RayHit rayHit; if (GJKToolbox.CCDSphereCast(new Ray(Toolbox.ZeroVector, velocity), minimumRadius, triangle, ref Toolbox.RigidIdentity, timeOfImpact, out rayHit) && rayHit.T > Toolbox.BigEpsilon) { if (sidedness != TriangleSidedness.DoubleSided) { System.Numerics.Vector3 AB, AC; Vector3Ex.Subtract(ref triangle.vB, ref triangle.vA, out AB); Vector3Ex.Subtract(ref triangle.vC, ref triangle.vA, out AC); System.Numerics.Vector3 normal; Vector3Ex.Cross(ref AB, ref AC, out normal); float dot; Vector3Ex.Dot(ref normal, ref rayHit.Normal, out dot); //Only perform sweep if the object is in danger of hitting the object. //Triangles can be one sided, so check the impact normal against the triangle normal. if (sidedness == TriangleSidedness.Counterclockwise && dot < 0 || sidedness == TriangleSidedness.Clockwise && dot > 0) { timeOfImpact = rayHit.T; } } else { timeOfImpact = rayHit.T; } } } PhysicsThreadResources.GiveBack(triangle); } } }
private void DrawGlContent(DrawEventArgs e) { var gcodeOptions = sceneContext.RendererOptions; if (gcodeOptions.GCodeModelView) { modelRenderStyle = ModelRenderStyle.WireframeAndSolid; } else { modelRenderStyle = ModelRenderStyle.None; } foreach (var drawable in drawables.Where(d => d.DrawStage == DrawStage.First)) { if (drawable.Enabled) { drawable.Draw(this, e, Matrix4X4.Identity, this.World); } } GLHelper.SetGlContext(this.World, renderSource.TransformToScreenSpace(renderSource.LocalBounds), lighting); foreach (var drawable in drawables.Where(d => d.DrawStage == DrawStage.OpaqueContent)) { if (drawable.Enabled) { drawable.Draw(this, e, Matrix4X4.Identity, this.World); } } // Draw solid objects, extract transparent var transparentMeshes = new List <Object3DView>(); var selectedItem = scene.SelectedItem; bool suppressNormalDraw = false; if (selectedItem != null) { // Invoke existing IEditorDraw when iterating items if (selectedItem is IEditorDraw editorDraw) { // TODO: Putting the drawing code in the IObject3D means almost certain bindings to MatterControl in IObject3D. If instead // we had a UI layer object that used binding to register scene drawing hooks for specific types, we could avoid the bindings editorDraw.DrawEditor(this, transparentMeshes, e, ref suppressNormalDraw); } } foreach (var item in scene.Children) { if (item.Visible && (item != selectedItem || suppressNormalDraw == false)) { DrawObject(item, transparentMeshes, e); } } if (sceneContext.Printer?.Connection?.serialPort is PrinterEmulator.Emulator emulator) { void NozzlePositionChanged(object s, EventArgs e2) { // limit max number of updates per second to 10 if (UiThread.CurrentTimerMs > lastEmulatorDrawMs + 100) { UiThread.RunOnIdle(Invalidate); // set it to now lastEmulatorDrawMs = UiThread.CurrentTimerMs; } } var matrix = Matrix4X4.CreateTranslation(emulator.CurrentPosition + new Vector3(.5, .5, 5)); GLHelper.Render(emulatorNozzleMesh, MaterialRendering.Color(emulator.ExtruderIndex), matrix, RenderTypes.Shaded, matrix * World.ModelviewMatrix); if (!emulatorHooked) { emulator.DestinationChanged += NozzlePositionChanged; emulatorHooked = true; } Closed += (s, e3) => emulator.DestinationChanged -= NozzlePositionChanged; } transparentMeshes.Sort(BackToFrontXY); var bedNormalInViewSpace = Vector3Ex.TransformNormal(Vector3.UnitZ, World.ModelviewMatrix).GetNormal(); var pointOnBedInViewSpace = Vector3Ex.Transform(new Vector3(10, 10, 0), World.ModelviewMatrix); var lookingDownOnBed = Vector3Ex.Dot(bedNormalInViewSpace, pointOnBedInViewSpace) < 0; floorDrawable.LookingDownOnBed = lookingDownOnBed; if (lookingDownOnBed) { floorDrawable.Draw(this, e, Matrix4X4.Identity, this.World); } var wireColor = Color.Transparent; switch (modelRenderStyle) { case ModelRenderStyle.Wireframe: wireColor = darkWireframe; break; case ModelRenderStyle.WireframeAndSolid: wireColor = lightWireframe; break; } // Draw transparent objects foreach (var item in transparentMeshes) { var object3D = item.Object3D; GLHelper.Render( object3D.Mesh, item.Color, object3D.WorldMatrix(), RenderTypes.Outlines, object3D.WorldMatrix() * World.ModelviewMatrix, wireColor, allowBspRendering: transparentMeshes.Count < 1000); } if (!lookingDownOnBed) { floorDrawable.Draw(this, e, Matrix4X4.Identity, this.World); } DrawInteractionVolumes(e); foreach (var drawable in drawables.Where(d => d.DrawStage == DrawStage.TransparentContent)) { if (drawable.Enabled) { drawable.Draw(this, e, Matrix4X4.Identity, this.World); } } GLHelper.UnsetGlContext(); // Invoke DrawStage.Last item drawables foreach (var item in scene.Children) { // HACK: Consider how shared code in DrawObject can be reused to prevent duplicate execution bool isSelected = selectedItem != null && selectedItem.DescendantsAndSelf().Any((i) => i == item); foreach (var itemDrawable in itemDrawables.Where(d => d.DrawStage == DrawStage.Last && d.Enabled)) { itemDrawable.Draw(this, item, isSelected, e, Matrix4X4.Identity, this.World); } } // Invoke DrawStage.Last scene drawables foreach (var drawable in drawables.Where(d => d.DrawStage == DrawStage.Last)) { if (drawable.Enabled) { drawable.Draw(this, e, Matrix4X4.Identity, this.World); } } }
public static bool Check( BasePlayer player, Construction construction, Vector3 position, Quaternion rotation) { OBB obb; ((OBB) ref obb).\u002Ector(position, rotation, construction.bounds); float radius = ((Vector3) ref obb.extents).get_magnitude() + 2f; List <BuildingBlock> list = (List <BuildingBlock>)Pool.GetList <BuildingBlock>(); Vis.Entities <BuildingBlock>((Vector3)obb.position, radius, list, 2097152, (QueryTriggerInteraction)2); uint num = 0; for (int index = 0; index < list.Count; ++index) { BuildingBlock buildingBlock = list[index]; Construction construction1 = construction; Construction blockDefinition = buildingBlock.blockDefinition; Vector3 vector3_1 = position; Vector3 position1 = ((Component)buildingBlock).get_transform().get_position(); Quaternion quaternion = rotation; Quaternion rotation1 = ((Component)buildingBlock).get_transform().get_rotation(); BuildingProximity.ProximityInfo proximity1 = BuildingProximity.GetProximity(construction1, vector3_1, quaternion, blockDefinition, position1, rotation1); BuildingProximity.ProximityInfo proximity2 = BuildingProximity.GetProximity(blockDefinition, position1, rotation1, construction1, vector3_1, quaternion); BuildingProximity.ProximityInfo proximityInfo = new BuildingProximity.ProximityInfo(); proximityInfo.hit = proximity1.hit || proximity2.hit; proximityInfo.connection = proximity1.connection || proximity2.connection; if ((double)proximity1.sqrDist <= (double)proximity2.sqrDist) { proximityInfo.line = proximity1.line; proximityInfo.sqrDist = proximity1.sqrDist; } else { proximityInfo.line = proximity2.line; proximityInfo.sqrDist = proximity2.sqrDist; } if (proximityInfo.connection) { BuildingManager.Building building = buildingBlock.GetBuilding(); if (building != null) { BuildingPrivlidge buildingPrivilege = building.GetDominatingBuildingPrivilege(); if (Object.op_Inequality((Object)buildingPrivilege, (Object)null)) { if (!construction.canBypassBuildingPermission && !buildingPrivilege.IsAuthed(player)) { Construction.lastPlacementError = "Cannot attach to unauthorized building"; // ISSUE: cast to a reference type Pool.FreeList <BuildingBlock>((List <M0>&) ref list); return(true); } if (num == 0U) { num = building.ID; } else if ((int)num != (int)building.ID) { Construction.lastPlacementError = "Cannot connect two buildings with cupboards"; // ISSUE: cast to a reference type Pool.FreeList <BuildingBlock>((List <M0>&) ref list); return(true); } } } } if (proximityInfo.hit) { Vector3 vector3_2 = Vector3.op_Subtraction((Vector3)proximityInfo.line.point1, (Vector3)proximityInfo.line.point0); if ((double)Mathf.Abs((float)vector3_2.y) <= 1.49000000953674 && (double)Vector3Ex.Magnitude2D(vector3_2) <= 1.49000000953674) { Construction.lastPlacementError = "Not enough space"; // ISSUE: cast to a reference type Pool.FreeList <BuildingBlock>((List <M0>&) ref list); return(true); } } } // ISSUE: cast to a reference type Pool.FreeList <BuildingBlock>((List <M0>&) ref list); return(false); }
public override void OnAttacked(HitInfo info) { bool canGather = info.CanGather; float num1 = Time.get_time() - this.lastHitTime; this.lastHitTime = Time.get_time(); if (!this.hasBonusGame || !canGather || Object.op_Equality((Object)info.Initiator, (Object)null) || this.BonusActive() && !this.DidHitMarker(info)) { base.OnAttacked(info); } else { if (Object.op_Inequality((Object)this.xMarker, (Object)null) && !info.DidGather && (double)info.gatherScale > 0.0) { this.xMarker.ClientRPC <int>((Connection)null, "MarkerHit", this.currentBonusLevel); ++this.currentBonusLevel; info.gatherScale = 1f + Mathf.Clamp((float)this.currentBonusLevel * 0.125f, 0.0f, 1f); } Vector3 vector3_1 = Object.op_Inequality((Object)this.xMarker, (Object)null) ? ((Component)this.xMarker).get_transform().get_position() : info.HitPositionWorld; this.CleanupMarker(); Vector3 vector3_2 = Vector3Ex.Direction2D(((Component)this).get_transform().get_position(), vector3_1); Vector3 vector3_3 = Vector3.Lerp(Vector3.op_UnaryNegation(vector3_2), Vector3.op_Multiply(Vector3.Cross(vector3_2, Vector3.get_up()), this.lastDirection), Random.Range(0.5f, 0.5f)); Vector3 pos = ((Component)this).get_transform().InverseTransformPoint(this.GetCollider().ClosestPoint(((Component)this).get_transform().TransformPoint(Vector3.op_Multiply(((Component)this).get_transform().InverseTransformDirection(((Vector3) ref vector3_3).get_normalized()), 2.5f)))); Vector3 vector3_4 = ((Component)this).get_transform().TransformPoint(pos); Vector3 vector3_5 = ((Component)this).get_transform().InverseTransformPoint(info.HitPositionWorld); pos.y = vector3_5.y; Vector3 vector3_6 = ((Component)this).get_transform().InverseTransformPoint(info.Initiator.CenterPoint()); float num2 = Mathf.Max(0.75f, (float)vector3_6.y); float num3 = (float)(vector3_6.y + 0.5); pos.y = (__Null)(double)Mathf.Clamp((float)(pos.y + (double)Random.Range(0.1f, 0.2f) * (Random.Range(0, 2) == 0 ? -1.0 : 1.0)), num2, num3); Vector3 vector3_7 = Vector3Ex.Direction2D(((Component)this).get_transform().get_position(), vector3_4); Vector3 vector3_8 = vector3_7; QuaternionEx.LookRotationNormal(Vector3.op_UnaryNegation(((Component)this).get_transform().InverseTransformDirection(vector3_7)), Vector3.get_zero()); pos = ((Component)this).get_transform().TransformPoint(pos); Quaternion rot = QuaternionEx.LookRotationNormal(Vector3.op_UnaryNegation(vector3_8), Vector3.get_zero()); this.xMarker = GameManager.server.CreateEntity("assets/content/nature/treesprefabs/trees/effects/tree_marking.prefab", pos, rot, true); this.xMarker.Spawn(); if ((double)num1 > 5.0) { this.StartBonusGame(); } base.OnAttacked(info); if ((double)this.health <= 0.0) { return; } this.lastAttackDamage = info.damageTypes.Total(); int num4 = Mathf.CeilToInt(this.health / this.lastAttackDamage); if (num4 < 2) { this.ClientRPC <int>((Connection)null, "CrackSound", 1); } else { if (num4 >= 5) { return; } this.ClientRPC <int>((Connection)null, "CrackSound", 0); } } }
public AIMovePoint GetBestRoamPosition(Vector3 start) { AIInformationZone informationZone = this.GetInformationZone(); if (Object.op_Equality((Object)informationZone, (Object)null)) { return((AIMovePoint)null); } float num1 = -1f; AIMovePoint aiMovePoint = (AIMovePoint)null; foreach (AIMovePoint movePoint in informationZone.movePoints) { if (((Component)((Component)movePoint).get_transform().get_parent()).get_gameObject().get_activeSelf()) { float num2 = 0.0f + Mathf.InverseLerp(-1f, 1f, Vector3.Dot(this.eyes.BodyForward(), Vector3Ex.Direction2D(((Component)movePoint).get_transform().get_position(), this.eyes.position))) * 100f; float num3 = Vector3.Distance(this.ServerPosition, ((Component)movePoint).get_transform().get_position()); if (!movePoint.IsUsedForRoaming()) { float num4 = Mathf.Abs((float)(this.ServerPosition.y - ((Component)movePoint).get_transform().get_position().y)); float num5 = num2 + (float)((1.0 - (double)Mathf.InverseLerp(1f, 10f, num4)) * 100.0); if ((double)num4 <= 5.0) { if ((double)num3 > 5.0) { num5 += (float)((1.0 - (double)Mathf.InverseLerp(5f, 20f, num3)) * 50.0); } if ((double)num5 > (double)num1) { aiMovePoint = movePoint; num1 = num5; } } } } } return(aiMovePoint); }
public bool AtPatrolDestination() { return(Vector3Ex.Distance2D(this.brain.mainInterestPoint, this.brain.GetEntity().GetPosition()) < CH47AIBrain.PatrolState.patrolApproachDist); }
private Matrix4X4 GetRotationTransform(IObject3D selectedItem, out double radius) { Matrix4X4 rotationCenterTransform; AxisAlignedBoundingBox currentSelectedBounds = selectedItem.GetAxisAlignedBoundingBox(); Vector3 controlCenter = GetControlCenter(selectedItem); Vector3 rotationCenter = GetRotationCenter(selectedItem, currentSelectedBounds); if (mouseDownInfo != null) { rotationCenter = mouseDownInfo.SelectedObjectRotationCenter; controlCenter = mouseDownInfo.ControlCenter; } double distBetweenPixelsWorldSpace = InteractionContext.World.GetWorldUnitsPerScreenPixelAtPosition(rotationCenter); double lengthFromCenterToControl = (rotationCenter - controlCenter).Length; radius = lengthFromCenterToControl * (1 / distBetweenPixelsWorldSpace); rotationTransformScale = distBetweenPixelsWorldSpace; rotationCenterTransform = Matrix4X4.CreateScale(distBetweenPixelsWorldSpace) * Matrix4X4.CreateTranslation(rotationCenter); var center = Vector3Ex.Transform(Vector3.Zero, rotationCenterTransform); switch (RotationAxis) { case 0: { rotationCenterTransform = Matrix4X4.CreateTranslation(-center) * Matrix4X4.CreateRotation(new Vector3(0, -MathHelper.Tau / 4, 0)) * Matrix4X4.CreateRotation(new Vector3(-MathHelper.Tau / 4, 0, 0)) * rotationCenterTransform; var center2 = Vector3Ex.Transform(Vector3.Zero, rotationCenterTransform); rotationCenterTransform *= Matrix4X4.CreateTranslation(center - center2); } break; case 1: { rotationCenterTransform = Matrix4X4.CreateTranslation(-center) * Matrix4X4.CreateRotation(new Vector3(MathHelper.Tau / 4, 0, 0)) * Matrix4X4.CreateRotation(new Vector3(0, MathHelper.Tau / 4, 0)) * rotationCenterTransform; var center2 = Vector3Ex.Transform(Vector3.Zero, rotationCenterTransform); rotationCenterTransform *= Matrix4X4.CreateTranslation(center - center2); } break; case 2: break; } return(rotationCenterTransform); }
private static void AddRevolveStrip(IVertexSource vertexSource, Mesh mesh, double startAngle, double endAngle, bool revolveAroundZ) { Vector3 lastPosition = Vector3.Zero; Vector3 firstPosition = Vector3.Zero; foreach (var vertexData in vertexSource.Vertices()) { if (vertexData.IsStop) { break; } if (vertexData.IsMoveTo) { firstPosition = new Vector3(vertexData.position.X, 0, vertexData.position.Y); if (!revolveAroundZ) { firstPosition = new Vector3(vertexData.position.X, vertexData.position.Y, 0); } lastPosition = firstPosition; } if (vertexData.IsLineTo || vertexData.IsClose) { var currentPosition = new Vector3(vertexData.position.X, 0, vertexData.position.Y); if (!revolveAroundZ) { currentPosition = new Vector3(vertexData.position.X, vertexData.position.Y, 0); } if (vertexData.IsClose) { currentPosition = firstPosition; } if (currentPosition.X != 0 || lastPosition.X != 0) { if (revolveAroundZ) { mesh.CreateFace(new Vector3[] { Vector3Ex.Transform(currentPosition, Matrix4X4.CreateRotationZ(endAngle)), Vector3Ex.Transform(currentPosition, Matrix4X4.CreateRotationZ(startAngle)), Vector3Ex.Transform(lastPosition, Matrix4X4.CreateRotationZ(startAngle)), Vector3Ex.Transform(lastPosition, Matrix4X4.CreateRotationZ(endAngle)), }); } else { mesh.CreateFace(new Vector3[] { Vector3Ex.Transform(currentPosition, Matrix4X4.CreateRotationY(endAngle)), Vector3Ex.Transform(currentPosition, Matrix4X4.CreateRotationY(startAngle)), Vector3Ex.Transform(lastPosition, Matrix4X4.CreateRotationY(startAngle)), Vector3Ex.Transform(lastPosition, Matrix4X4.CreateRotationY(endAngle)), }); } } lastPosition = currentPosition; } } }
public override void StateThink(float delta) { bool flag; Vector3 entity = this.brain.GetEntity().transform.position; CH47LandingZone closest = CH47LandingZone.GetClosest(this.brain.GetEntity().landingTarget); if (!closest) { return; } float single = this.brain.GetEntity().rigidBody.velocity.magnitude; Vector3.Distance(closest.transform.position, entity); float single1 = Vector3Ex.Distance2D(closest.transform.position, entity); Mathf.InverseLerp(1f, 20f, single1); bool flag1 = single1 < 100f; bool flag2 = (single1 <= 15f ? false : entity.y < closest.transform.position.y + 10f); this.brain.GetEntity().EnableFacingOverride(flag1); this.brain.GetEntity().SetAltitudeProtection(flag2); flag = (Mathf.Abs(closest.transform.position.y - entity.y) >= 3f || single1 > 5f ? false : single < 1f); if (flag) { this.landedForSeconds += delta; if (this.lastLandtime == 0f) { this.lastLandtime = Time.time; } } float single2 = 1f - Mathf.InverseLerp(0f, 7f, single1); this.landingHeight = this.landingHeight - 4f * single2 * Time.deltaTime; if (this.landingHeight < -5f) { this.landingHeight = -5f; } this.brain.GetEntity().SetAimDirection(closest.transform.forward); this.brain.GetEntity().SetMoveTarget(this.brain.mainInterestPoint + new Vector3(0f, this.landingHeight, 0f)); if (flag) { if (this.landedForSeconds > 1f && Time.time > this.nextDismountTime) { BaseVehicle.MountPointInfo[] mountPointInfoArray = this.brain.GetEntity().mountPoints; int num = 0; while (num < (int)mountPointInfoArray.Length) { BaseVehicle.MountPointInfo mountPointInfo = mountPointInfoArray[num]; if (!mountPointInfo.mountable || !mountPointInfo.mountable.IsMounted()) { num++; } else { this.nextDismountTime = Time.time + 0.5f; mountPointInfo.mountable.DismountAllPlayers(); break; } } } if (this.landedForSeconds > 8f) { this.brain.GetComponent <CH47AIBrain>().age = Single.PositiveInfinity; } } }
public bool IsNaNOrInfinity() { return(Vector3Ex.IsNaNOrInfinity(this.PointStart) || Vector3Ex.IsNaNOrInfinity(this.PointEnd) || (Vector3Ex.IsNaNOrInfinity(this.HitPositionWorld) || Vector3Ex.IsNaNOrInfinity(this.HitPositionLocal)) || (Vector3Ex.IsNaNOrInfinity(this.HitNormalWorld) || Vector3Ex.IsNaNOrInfinity(this.HitNormalLocal) || (Vector3Ex.IsNaNOrInfinity(this.ProjectileVelocity) || float.IsNaN(this.ProjectileDistance))) || float.IsInfinity(this.ProjectileDistance)); }
public override void StateThink(float delta) { base.StateThink(delta); float num1 = 2f; float num2 = 0.0f; if ((double)Time.get_time() > (double)this.lastCoverTime + (double)num1 && !this.isFleeing) { Vector3 hideFromPosition = Object.op_Implicit((Object)this.GetEntity().currentTarget) ? this.GetEntity().currentTarget.ServerPosition : Vector3.op_Addition(this.GetEntity().ServerPosition, Vector3.op_Multiply(this.GetEntity().LastAttackedDir, 30f)); float num3 = Object.op_Inequality((Object)this.GetEntity().currentTarget, (Object)null) ? this.GetEntity().DistanceToTarget() : 30f; AIInformationZone informationZone = this.GetEntity().GetInformationZone(); if (Object.op_Inequality((Object)informationZone, (Object)null)) { float secondsSinceAttacked = this.GetEntity().SecondsSinceAttacked; float minRange = (double)secondsSinceAttacked < 2.0 ? 2f : 0.0f; float maxRange = 20f; AICoverPoint bestCoverPoint = informationZone.GetBestCoverPoint(this.GetEntity().ServerPosition, hideFromPosition, minRange, maxRange, (BaseEntity)this.GetEntity()); if (Object.op_Implicit((Object)bestCoverPoint)) { bestCoverPoint.SetUsedBy((BaseEntity)this.GetEntity(), 5f); } Vector3 newDestination = Object.op_Equality((Object)bestCoverPoint, (Object)null) ? this.GetEntity().ServerPosition : ((Component)bestCoverPoint).get_transform().get_position(); this.GetEntity().SetDestination(newDestination); float num4 = Vector3.Distance(newDestination, this.GetEntity().ServerPosition); double target = (double)this.GetEntity().DistanceToTarget(); int num5 = (double)secondsSinceAttacked >= 4.0 ? 0 : ((double)this.GetEntity().AmmoFractionRemaining() <= 0.25 ? 1 : 0); int num6 = (double)this.GetEntity().healthFraction >= 0.5 || (double)secondsSinceAttacked >= 1.0 ? 0 : ((double)Time.get_time() > (double)num2 ? 1 : 0); if ((double)num3 > 6.0 && (double)num4 > 6.0 || Object.op_Equality((Object)this.GetEntity().currentTarget, (Object)null)) { this.isFleeing = true; float num7 = Time.get_time() + Random.Range(4f, 7f); } if ((double)num4 > 1.0) { this.GetEntity().ClearStationaryAimPoint(); } } this.lastCoverTime = Time.get_time(); } bool flag = (double)Vector3.Distance(this.GetEntity().ServerPosition, this.GetEntity().finalDestination) <= 0.25; if (!this.inCover & flag) { if (this.isFleeing) { this.GetEntity().SetStationaryAimPoint(Vector3.op_Addition(this.GetEntity().finalDestination, Vector3.op_Multiply(Vector3.op_UnaryNegation(this.GetEntity().eyes.BodyForward()), 5f))); } else if (Object.op_Implicit((Object)this.GetEntity().currentTarget)) { this.GetEntity().SetStationaryAimPoint(Vector3.op_Addition(this.GetEntity().ServerPosition, Vector3.op_Multiply(Vector3Ex.Direction2D(this.GetEntity().currentTarget.ServerPosition, this.GetEntity().ServerPosition), 5f))); } } this.inCover = flag; if (this.inCover) { this.timeInCover += delta; } else { this.timeInCover = 0.0f; } this.GetEntity().SetDucked(this.inCover); if (this.inCover) { this.isFleeing = false; } if (((double)this.GetEntity().AmmoFractionRemaining() == 0.0 || this.isFleeing ? 1 : (this.GetEntity().CanSeeTarget() || !this.inCover || (double)this.GetEntity().SecondsSinceDealtDamage <= 2.0 ? 0 : ((double)this.GetEntity().AmmoFractionRemaining() < 0.25 ? 1 : 0))) != 0) { this.GetEntity().AttemptReload(); } if (this.inCover) { return; } if ((double)this.TimeInState() > 1.0 && this.isFleeing) { this.GetEntity().SetDesiredSpeed(HumanNPC.SpeedType.Sprint); } else { this.GetEntity().SetDesiredSpeed(HumanNPC.SpeedType.Walk); } }
///<summary> /// Performs the frame's configuration step. ///</summary> ///<param name="dt">Timestep duration.</param> public override void Update(float dt) { entityADynamic = entityA != null && entityA.isDynamic; entityBDynamic = entityB != null && entityB.isDynamic; contactCount = contactManifoldConstraint.penetrationConstraints.Count; switch (contactCount) { case 1: manifoldCenter = contactManifoldConstraint.penetrationConstraints.Elements[0].contact.Position; break; case 2: Vector3Ex.Add(ref contactManifoldConstraint.penetrationConstraints.Elements[0].contact.Position, ref contactManifoldConstraint.penetrationConstraints.Elements[1].contact.Position, out manifoldCenter); manifoldCenter.X *= .5f; manifoldCenter.Y *= .5f; manifoldCenter.Z *= .5f; break; case 3: Vector3Ex.Add(ref contactManifoldConstraint.penetrationConstraints.Elements[0].contact.Position, ref contactManifoldConstraint.penetrationConstraints.Elements[1].contact.Position, out manifoldCenter); Vector3Ex.Add(ref contactManifoldConstraint.penetrationConstraints.Elements[2].contact.Position, ref manifoldCenter, out manifoldCenter); manifoldCenter.X *= .333333333f; manifoldCenter.Y *= .333333333f; manifoldCenter.Z *= .333333333f; break; case 4: //This isn't actually the center of the manifold. Is it good enough? Sure seems like it. Vector3Ex.Add(ref contactManifoldConstraint.penetrationConstraints.Elements[0].contact.Position, ref contactManifoldConstraint.penetrationConstraints.Elements[1].contact.Position, out manifoldCenter); Vector3Ex.Add(ref contactManifoldConstraint.penetrationConstraints.Elements[2].contact.Position, ref manifoldCenter, out manifoldCenter); Vector3Ex.Add(ref contactManifoldConstraint.penetrationConstraints.Elements[3].contact.Position, ref manifoldCenter, out manifoldCenter); manifoldCenter.X *= .25f; manifoldCenter.Y *= .25f; manifoldCenter.Z *= .25f; break; default: manifoldCenter = Toolbox.NoVector; break; } //Compute the three dimensional relative velocity at the point. System.Numerics.Vector3 velocityA, velocityB; if (entityA != null) { Vector3Ex.Subtract(ref manifoldCenter, ref entityA.position, out ra); Vector3Ex.Cross(ref entityA.angularVelocity, ref ra, out velocityA); Vector3Ex.Add(ref velocityA, ref entityA.linearVelocity, out velocityA); } else { velocityA = new System.Numerics.Vector3(); } if (entityB != null) { Vector3Ex.Subtract(ref manifoldCenter, ref entityB.position, out rb); Vector3Ex.Cross(ref entityB.angularVelocity, ref rb, out velocityB); Vector3Ex.Add(ref velocityB, ref entityB.linearVelocity, out velocityB); } else { velocityB = new System.Numerics.Vector3(); } Vector3Ex.Subtract(ref velocityA, ref velocityB, out relativeVelocity); //Get rid of the normal velocity. System.Numerics.Vector3 normal = contactManifoldConstraint.penetrationConstraints.Elements[0].contact.Normal; float normalVelocityScalar = normal.X * relativeVelocity.X + normal.Y * relativeVelocity.Y + normal.Z * relativeVelocity.Z; relativeVelocity.X -= normalVelocityScalar * normal.X; relativeVelocity.Y -= normalVelocityScalar * normal.Y; relativeVelocity.Z -= normalVelocityScalar * normal.Z; //Create the jacobian entry and decide the friction coefficient. float length = relativeVelocity.LengthSquared(); if (length > Toolbox.Epsilon) { length = (float)Math.Sqrt(length); float inverseLength = 1 / length; linearA.M11 = relativeVelocity.X * inverseLength; linearA.M12 = relativeVelocity.Y * inverseLength; linearA.M13 = relativeVelocity.Z * inverseLength; friction = length > CollisionResponseSettings.StaticFrictionVelocityThreshold ? contactManifoldConstraint.materialInteraction.KineticFriction : contactManifoldConstraint.materialInteraction.StaticFriction; } else { friction = contactManifoldConstraint.materialInteraction.StaticFriction; //If there was no velocity, try using the previous frame's jacobian... if it exists. //Reusing an old one is okay since jacobians are cleared when a contact is initialized. if (!(linearA.M11 != 0 || linearA.M12 != 0 || linearA.M13 != 0)) { //Otherwise, just redo it all. //Create arbitrary axes. System.Numerics.Vector3 axis1; Vector3Ex.Cross(ref normal, ref Toolbox.RightVector, out axis1); length = axis1.LengthSquared(); if (length > Toolbox.Epsilon) { length = (float)Math.Sqrt(length); float inverseLength = 1 / length; linearA.M11 = axis1.X * inverseLength; linearA.M12 = axis1.Y * inverseLength; linearA.M13 = axis1.Z * inverseLength; } else { Vector3Ex.Cross(ref normal, ref Toolbox.UpVector, out axis1); axis1.Normalize(); linearA.M11 = axis1.X; linearA.M12 = axis1.Y; linearA.M13 = axis1.Z; } } } //Second axis is first axis x normal linearA.M21 = (linearA.M12 * normal.Z) - (linearA.M13 * normal.Y); linearA.M22 = (linearA.M13 * normal.X) - (linearA.M11 * normal.Z); linearA.M23 = (linearA.M11 * normal.Y) - (linearA.M12 * normal.X); //Compute angular jacobians if (entityA != null) { //angularA 1 = ra x linear axis 1 angularA.M11 = (ra.Y * linearA.M13) - (ra.Z * linearA.M12); angularA.M12 = (ra.Z * linearA.M11) - (ra.X * linearA.M13); angularA.M13 = (ra.X * linearA.M12) - (ra.Y * linearA.M11); //angularA 2 = ra x linear axis 2 angularA.M21 = (ra.Y * linearA.M23) - (ra.Z * linearA.M22); angularA.M22 = (ra.Z * linearA.M21) - (ra.X * linearA.M23); angularA.M23 = (ra.X * linearA.M22) - (ra.Y * linearA.M21); } //angularB 1 = linear axis 1 x rb if (entityB != null) { angularB.M11 = (linearA.M12 * rb.Z) - (linearA.M13 * rb.Y); angularB.M12 = (linearA.M13 * rb.X) - (linearA.M11 * rb.Z); angularB.M13 = (linearA.M11 * rb.Y) - (linearA.M12 * rb.X); //angularB 2 = linear axis 2 x rb angularB.M21 = (linearA.M22 * rb.Z) - (linearA.M23 * rb.Y); angularB.M22 = (linearA.M23 * rb.X) - (linearA.M21 * rb.Z); angularB.M23 = (linearA.M21 * rb.Y) - (linearA.M22 * rb.X); } //Compute inverse effective mass matrix Matrix2x2 entryA, entryB; //these are the transformed coordinates Matrix2x3 transform; Matrix3x2 transpose; if (entityADynamic) { Matrix2x3.Multiply(ref angularA, ref entityA.inertiaTensorInverse, out transform); Matrix2x3.Transpose(ref angularA, out transpose); Matrix2x2.Multiply(ref transform, ref transpose, out entryA); entryA.M11 += entityA.inverseMass; entryA.M22 += entityA.inverseMass; } else { entryA = new Matrix2x2(); } if (entityBDynamic) { Matrix2x3.Multiply(ref angularB, ref entityB.inertiaTensorInverse, out transform); Matrix2x3.Transpose(ref angularB, out transpose); Matrix2x2.Multiply(ref transform, ref transpose, out entryB); entryB.M11 += entityB.inverseMass; entryB.M22 += entityB.inverseMass; } else { entryB = new Matrix2x2(); } velocityToImpulse.M11 = -entryA.M11 - entryB.M11; velocityToImpulse.M12 = -entryA.M12 - entryB.M12; velocityToImpulse.M21 = -entryA.M21 - entryB.M21; velocityToImpulse.M22 = -entryA.M22 - entryB.M22; Matrix2x2.Invert(ref velocityToImpulse, out velocityToImpulse); }
public override void OnMouseMove(Mouse3DEventArgs mouseEvent3D) { IObject3D selectedItem = RootSelection; if (selectedItem != null) { var controlCenter = GetControlCenter(selectedItem); if (mouseDownInfo != null) { controlCenter = mouseDownInfo.ControlCenter; } var hitPlane = new PlaneShape(RotationPlanNormal, Vector3Ex.Dot(RotationPlanNormal, controlCenter), null); IntersectInfo hitOnRotationPlane = hitPlane.GetClosestIntersection(mouseEvent3D.MouseRay); if (hitOnRotationPlane != null) { AxisAlignedBoundingBox currentSelectedBounds = selectedItem.GetAxisAlignedBoundingBox(); var selectedObjectRotationCenter = currentSelectedBounds.Center; if (mouseDownInfo != null) { selectedObjectRotationCenter = mouseDownInfo.SelectedObjectRotationCenter; } Vector3 cornerForAxis = GetCornerPosition(selectedItem); // move the rotation center to the correct side of the bounding box selectedObjectRotationCenter[RotationAxis] = cornerForAxis[RotationAxis]; mouseMoveInfo = new Mouse3DInfo( hitOnRotationPlane.HitPosition, selectedItem.Matrix, selectedObjectRotationCenter, controlCenter, RotationAxis); if (MouseDownOnControl && mouseDownInfo != null) { double rawDeltaRotationAngle = mouseMoveInfo.AngleOfHit - mouseDownInfo.AngleOfHit; double snapRadians = MathHelper.DegreesToRadians(1); // snap this position to the grid if (rawDeltaRotationAngle > 0) { SnappedRotationAngle = ((int)((rawDeltaRotationAngle / snapRadians) + .5)) * snapRadians; } else { SnappedRotationAngle = ((int)((rawDeltaRotationAngle / snapRadians) - .5)) * snapRadians; } int snappingIndex = GetSnapIndex(selectedItem, numSnapPoints); if (snappingIndex != -1) { SnappedRotationAngle = snappingIndex * MathHelper.Tau / numSnapPoints; } else if (InteractionContext.GuiSurface.ModifierKeys == Keys.Shift) { snapRadians = MathHelper.DegreesToRadians(45); if (rawDeltaRotationAngle > 0) { SnappedRotationAngle = ((int)((rawDeltaRotationAngle / snapRadians) + .5)) * snapRadians; } else { SnappedRotationAngle = ((int)((rawDeltaRotationAngle / snapRadians) - .5)) * snapRadians; } } if (SnappedRotationAngle < 0) { SnappedRotationAngle += MathHelper.Tau; } // check if this move crosses zero degrees if (lastSnappedRotation == 0 && SnappedRotationAngle != 0) { RotatingCW = DeltaAngle(0, SnappedRotationAngle) < 0; } else if ((DeltaAngle(0, SnappedRotationAngle) < 0 && DeltaAngle(0, lastSnappedRotation) > 0 && Math.Abs(DeltaAngle(0, lastSnappedRotation)) < 1) || (DeltaAngle(0, SnappedRotationAngle) > 0 && DeltaAngle(0, lastSnappedRotation) < 0 && Math.Abs(DeltaAngle(0, lastSnappedRotation)) < 1)) { // let's figure out which way we are going RotatingCW = DeltaAngle(0, SnappedRotationAngle) < 0 && DeltaAngle(0, lastSnappedRotation) > 0; } // undo the last rotation RotateAroundAxis(selectedItem, -lastSnappedRotation); // rotate it RotateAroundAxis(selectedItem, SnappedRotationAngle); lastSnappedRotation = SnappedRotationAngle; Invalidate(); } } } base.OnMouseMove(mouseEvent3D); }
public override void OnKilled(HitInfo info) { if (base.isClient || Interface.CallHook("OnEntityDestroy", this) != null) { return; } CreateExplosionMarker(10f); Effect.server.Run(explosionEffect.resourcePath, mainTurretEyePos.transform.position, Vector3.up, null, true); Vector3 zero = Vector3.zero; GameObject gibSource = servergibs.Get().GetComponent <ServerGib>()._gibSource; List <ServerGib> list = ServerGib.CreateGibs(servergibs.resourcePath, base.gameObject, gibSource, zero, 3f); for (int i = 0; i < 12 - maxCratesToSpawn; i++) { BaseEntity baseEntity = GameManager.server.CreateEntity(this.fireBall.resourcePath, base.transform.position, base.transform.rotation); if (!baseEntity) { continue; } float min = 3f; float max = 10f; Vector3 onUnitSphere = UnityEngine.Random.onUnitSphere; baseEntity.transform.position = base.transform.position + new Vector3(0f, 1.5f, 0f) + onUnitSphere * UnityEngine.Random.Range(-4f, 4f); Collider component = baseEntity.GetComponent <Collider>(); baseEntity.Spawn(); baseEntity.SetVelocity(zero + onUnitSphere * UnityEngine.Random.Range(min, max)); foreach (ServerGib item in list) { UnityEngine.Physics.IgnoreCollision(component, item.GetCollider(), true); } } for (int j = 0; j < maxCratesToSpawn; j++) { Vector3 onUnitSphere2 = UnityEngine.Random.onUnitSphere; onUnitSphere2.y = 0f; onUnitSphere2.Normalize(); Vector3 pos = base.transform.position + new Vector3(0f, 1.5f, 0f) + onUnitSphere2 * UnityEngine.Random.Range(2f, 3f); BaseEntity baseEntity2 = GameManager.server.CreateEntity(crateToDrop.resourcePath, pos, Quaternion.LookRotation(onUnitSphere2)); baseEntity2.Spawn(); LootContainer lootContainer = baseEntity2 as LootContainer; if ((bool)lootContainer) { lootContainer.Invoke(lootContainer.RemoveMe, 1800f); } Collider component2 = baseEntity2.GetComponent <Collider>(); Rigidbody rigidbody = baseEntity2.gameObject.AddComponent <Rigidbody>(); rigidbody.useGravity = true; rigidbody.collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic; rigidbody.mass = 2f; rigidbody.interpolation = RigidbodyInterpolation.Interpolate; rigidbody.velocity = zero + onUnitSphere2 * UnityEngine.Random.Range(1f, 3f); rigidbody.angularVelocity = Vector3Ex.Range(-1.75f, 1.75f); rigidbody.drag = 0.5f * (rigidbody.mass / 5f); rigidbody.angularDrag = 0.2f * (rigidbody.mass / 5f); FireBall fireBall = GameManager.server.CreateEntity(this.fireBall.resourcePath) as FireBall; if ((bool)fireBall) { fireBall.SetParent(baseEntity2); fireBall.Spawn(); fireBall.GetComponent <Rigidbody>().isKinematic = true; fireBall.GetComponent <Collider>().enabled = false; } baseEntity2.SendMessage("SetLockingEnt", fireBall.gameObject, SendMessageOptions.DontRequireReceiver); foreach (ServerGib item2 in list) { UnityEngine.Physics.IgnoreCollision(component2, item2.GetCollider(), true); } } base.OnKilled(info); }
private void DrawRotationCompass(IObject3D selectedItem, DrawGlContentEventArgs drawEventArgs) { if (InteractionContext.Scene.SelectedItem == null) { return; } double alphaValue = 1; if (!drawEventArgs.ZBuffered) { alphaValue = .3; } AxisAlignedBoundingBox currentSelectedBounds = selectedItem.GetAxisAlignedBoundingBox(); if (currentSelectedBounds.XSize > 100000) { // something is wrong the part is too big (probably in invalid selection) return; } if (mouseMoveInfo != null) { Matrix4X4 rotationCenterTransform = GetRotationTransform(selectedItem, out double radius); double innerRadius = radius + ringWidth / 2; double outerRadius = innerRadius + ringWidth; double snappingMarkRadius = outerRadius + 20; double startBlue = 0; double endBlue = MathHelper.Tau; double mouseAngle = 0; if (mouseMoveInfo != null) { mouseAngle = mouseMoveInfo.AngleOfHit; } if (mouseDownInfo != null) { mouseAngle = mouseDownInfo.AngleOfHit; } var graphics2DOpenGL = new Graphics2DOpenGL(); if (mouseDownInfo != null || MouseOver) { IVertexSource blueRing = new JoinPaths(new Arc(0, 0, outerRadius, outerRadius, startBlue, endBlue, Arc.Direction.CounterClockWise), new Arc(0, 0, innerRadius, innerRadius, startBlue, endBlue, Arc.Direction.ClockWise)); graphics2DOpenGL.RenderTransformedPath(rotationCenterTransform, blueRing, new Color(theme.PrimaryAccentColor, (int)(50 * alphaValue)), drawEventArgs.ZBuffered); // tick 60 marks DrawTickMarks(drawEventArgs, alphaValue, rotationCenterTransform, innerRadius, outerRadius, 60); } if (mouseDownInfo != null) { double startRed = mouseDownInfo.AngleOfHit; double endRed = SnappedRotationAngle + mouseDownInfo.AngleOfHit; if (!RotatingCW) { var temp = startRed; startRed = endRed; endRed = temp; } IVertexSource redAngle = new JoinPaths(new Arc(0, 0, 0, 0, startRed, endRed, Arc.Direction.CounterClockWise), new Arc(0, 0, innerRadius, innerRadius, startRed, endRed, Arc.Direction.ClockWise)); graphics2DOpenGL.RenderTransformedPath(rotationCenterTransform, redAngle, new Color(theme.PrimaryAccentColor, (int)(70 * alphaValue)), drawEventArgs.ZBuffered); // draw a line to the mouse on the rotation circle if (mouseMoveInfo != null && MouseDownOnControl) { var unitPosition = new Vector3(Math.Cos(mouseMoveInfo.AngleOfHit), Math.Sin(mouseMoveInfo.AngleOfHit), 0); Vector3 startPosition = Vector3Ex.Transform(unitPosition * innerRadius, rotationCenterTransform); var center = Vector3Ex.Transform(Vector3.Zero, rotationCenterTransform); if ((mouseMoveInfo.HitPosition - center).Length > rotationTransformScale * innerRadius) { InteractionContext.World.Render3DLine(startPosition, mouseMoveInfo.HitPosition, theme.PrimaryAccentColor, drawEventArgs.ZBuffered); } DrawSnappingMarks(drawEventArgs, mouseAngle, alphaValue, rotationCenterTransform, snappingMarkRadius, numSnapPoints, GetSnapIndex(selectedItem, numSnapPoints)); } } } }
public bool IsAtFinalDestination() { return(Vector3Ex.Distance2D(base.transform.position, finalDestination) <= stoppingDist); }
public bool DidHitMarker(HitInfo info) { return(!Object.op_Equality((Object)this.xMarker, (Object)null) && (double)Vector3.Dot(Vector3Ex.Direction2D(((Component)this).get_transform().get_position(), ((Component)this.xMarker).get_transform().get_position()), info.attackNormal) >= 0.3 && (double)Vector3.Distance(((Component)this.xMarker).get_transform().get_position(), info.HitPositionWorld) <= 0.200000002980232); }
internal void ApplyLinearImpulse(ref System.Numerics.Vector3 impulse) { System.Numerics.Vector3 velocityChange; Vector3Ex.Multiply(ref impulse, inverseMass, out velocityChange); Vector3Ex.Add(ref linearVelocity, ref velocityChange, out linearVelocity); }
public bool WithinVisionCone(BaseEntity other) { return((double)Vector3.Dot(this.eyes.BodyForward(), Vector3Ex.Direction(((Component)other).get_transform().get_position(), ((Component)this).get_transform().get_position())) >= (double)this.visionCone); }
internal void ApplyAngularImpulse(ref System.Numerics.Vector3 impulse) { System.Numerics.Vector3 velocityChange; Matrix3x3.Transform(ref impulse, ref inertiaTensorInverse, out velocityChange); Vector3Ex.Add(ref velocityChange, ref angularVelocity, out angularVelocity); }
public override StateStatus StateThink(float delta) { base.StateThink(delta); float num = 2f; float num2 = 0f; if (Time.time > lastCoverTime + num && !isFleeing) { Vector3 hideFromPosition = (GetEntity().currentTarget ? GetEntity().currentTarget.transform.position : (GetEntity().transform.position + GetEntity().LastAttackedDir * 30f)); float num3 = ((GetEntity().currentTarget != null) ? GetEntity().DistanceToTarget() : 30f); AIInformationZone informationZone = GetEntity().GetInformationZone(GetEntity().transform.position); if (informationZone != null) { float secondsSinceAttacked = GetEntity().SecondsSinceAttacked; float minRange = ((secondsSinceAttacked < 2f) ? 2f : 0f); float maxRange = 25f; if (currentCover != null) { currentCover.ClearIfUsedBy(GetEntity()); currentCover = null; } AICoverPoint bestCoverPoint = informationZone.GetBestCoverPoint(GetEntity().transform.position, hideFromPosition, minRange, maxRange, GetEntity()); if ((bool)bestCoverPoint) { bestCoverPoint.SetUsedBy(GetEntity(), 15f); currentCover = bestCoverPoint; } Vector3 vector = ((bestCoverPoint == null) ? GetEntity().transform.position : bestCoverPoint.transform.position); GetEntity().SetDestination(vector); float num4 = Vector3.Distance(vector, GetEntity().transform.position); bool flag2; int num5; if (secondsSinceAttacked < 4f) { flag2 = GetEntity().AmmoFractionRemaining() <= 0.25f; } else { num5 = 0; } bool flag3; int num6; if (GetEntity().healthFraction < 0.5f && secondsSinceAttacked < 1f) { flag3 = Time.time > num2; } else { num6 = 0; } if ((num3 > 6f && num4 > 8f) || GetEntity().currentTarget == null) { isFleeing = true; num2 = Time.time + Random.Range(4f, 7f); } if (num4 > 1f) { GetEntity().ClearStationaryAimPoint(); } } lastCoverTime = Time.time; } bool flag = Vector3.Distance(GetEntity().transform.position, GetEntity().finalDestination) <= 0.25f; if (!inCover && flag) { if (isFleeing) { GetEntity().SetStationaryAimPoint(GetEntity().finalDestination + -GetEntity().eyes.BodyForward() * 5f); } else if ((bool)GetEntity().currentTarget) { GetEntity().SetStationaryAimPoint(GetEntity().transform.position + Vector3Ex.Direction2D(GetEntity().currentTarget.transform.position, GetEntity().transform.position) * 5f); } } inCover = flag; if (inCover) { timeInCover += delta; } else { timeInCover = 0f; } GetEntity().SetDucked(inCover); if (inCover) { isFleeing = false; } if (GetEntity().AmmoFractionRemaining() == 0f || isFleeing || (!GetEntity().CanSeeTarget() && inCover && GetEntity().SecondsSinceDealtDamage > 2f && GetEntity().AmmoFractionRemaining() < 0.25f)) { GetEntity().AttemptReload(); } if (!inCover) { if (base.TimeInState > 1f && isFleeing) { GetEntity().SetDesiredSpeed(HumanNPC.SpeedType.Sprint); } else { GetEntity().SetDesiredSpeed(HumanNPC.SpeedType.Walk); } } return(StateStatus.Running); }
// Returns an intersection if found with distance maxDistance // viewDir must be a unit vector. // intersectDistance and visPoint are returned values. bool FindIntersectionNT(Vector3 viewPos, Vector3 viewDir, double maxDistance, out double intersectDistance, out Vector2 returnedPoint) { double maxFrontDist = double.NegativeInfinity; double minBackDist = double.PositiveInfinity; int frontType, backType; // 0, 1, 2 = top, bottom, side // Start with the bounding planes if (IsRightCylinder()) { double pdotn = Vector3Ex.Dot(viewPos, CenterAxis) - CenterDotAxis; double udotn = Vector3Ex.Dot(viewDir, CenterAxis); if (pdotn > HalfHeight) { if (udotn >= 0.0) { return(false); // Above top plane pointing up } // Hits top from above maxFrontDist = (HalfHeight - pdotn) / udotn; frontType = 0; minBackDist = -(HalfHeight + pdotn) / udotn; backType = 1; } else if (pdotn < -HalfHeight) { if (udotn <= 0.0) { return(false); // Below bottom, pointing down } // Hits bottom plane from below maxFrontDist = -(HalfHeight + pdotn) / udotn; frontType = 1; minBackDist = (HalfHeight - pdotn) / udotn; backType = 0; } else if (udotn < 0.0) { // Inside, pointing down minBackDist = -(HalfHeight + pdotn) / udotn; backType = 1; } else if (udotn > 0.0) { // Inside, pointing up minBackDist = (HalfHeight - pdotn) / udotn; backType = 0; } } else { // Has two bounding planes (not right cylinder) // First handle the top plane double pdotnCap = Vector3Ex.Dot(TopNormal, viewPos); double udotnCap = Vector3Ex.Dot(TopNormal, viewDir); if (pdotnCap > TopPlaneCoef) { if (udotnCap >= 0.0) { return(false); // Above top plane, pointing up } maxFrontDist = (TopPlaneCoef - pdotnCap) / udotnCap; frontType = 0; } else if (pdotnCap < TopPlaneCoef) { if (udotnCap > 0.0) { // Below top plane, pointing up minBackDist = (TopPlaneCoef - pdotnCap) / udotnCap; backType = 0; } } // Second, handle the bottom plane pdotnCap = Vector3Ex.Dot(BottomNormal, viewPos); udotnCap = Vector3Ex.Dot(BottomNormal ^ viewDir); if (pdotnCap < BottomPlaneCoef) { if (udotnCap > 0.0) { double newBackDist = (BottomPlaneCoef - pdotnCap) / udotnCap; if (newBackDist < maxFrontDist) { return(false); } if (newBackDist < minBackDist) { minBackDist = newBackDist; backType = 1; } } } else if (pdotnCap > BottomPlaneCoef) { if (udotnCap >= 0.0) { return(false); // Above bottom plane, pointing up (away) } // Above bottom plane, pointing down double newFrontDist = (BottomPlaneCoef - pdotnCap) / udotnCap; if (newFrontDist > minBackDist) { return(false); } if (newFrontDist > maxFrontDist) { maxFrontDist = newFrontDist; frontType = 1; } } } if (maxFrontDist > maxDistance) { return(false); } // Now handle the cylinder sides Vector3 v = viewPos; v -= Center; double pdotuA = Vector3Ex.Dot(v, AxisA); double pdotuB = Vector3Ex.Dot(v, AxisB); double udotuA = Vector3Ex.Dot(viewDir, AxisA); double udotuB = Vector3Ex.Dot(viewDir, AxisB); double C = pdotuA * pdotuA + pdotuB * pdotuB - 1.0; double B = (pdotuA * udotuA + pdotuB * udotuB); if (C >= 0.0 && B > 0.0) { return(false); // Pointing away from the cylinder } B += B; // Double B for final 2.0 factor double A = udotuA * udotuA + udotuB * udotuB; double alpha1, alpha2; // The roots, in order int numRoots = QuadraticSolveRealSafe(A, B, C, out alpha1, out alpha2); if (numRoots == 0) { return(false); // No intersection } if (alpha1 > maxFrontDist) { if (alpha1 > minBackDist) { return(false); } maxFrontDist = alpha1; frontType = 2; } if (numRoots == 2 && alpha2 < minBackDist) { if (alpha2 < maxFrontDist) { return(false); } minBackDist = alpha2; backType = 2; } // Put it all together: double alpha; int hitSurface; if (maxFrontDist > 0.0) { returnedPoint.SetFrontFace(); // Hit from outside alpha = maxFrontDist; hitSurface = frontType; } else { returnedPoint.SetBackFace(); // Hit from inside alpha = minBackDist; hitSurface = backType; } if (alpha >= maxDistance) { return(false); } intersectDistance = alpha; // Set v to the intersection point v = viewDir; v *= alpha; v += viewPos; returnedPoint.SetPosition(v); // Intersection point // Now set v equal to returned position relative to the center v -= Center; double vdotuA = Vector3(v, AxisA); double vdotuB = Vector3(v, AxisB); switch (hitSurface) { case 0: // Top surface returnedPoint.SetNormal(TopNormal); if (returnedPoint.IsFrontFacing()) { returnedPoint.SetMaterial(TopOuterMat); } else { returnedPoint.SetMaterial(TopInnerMat); } // Calculate U-V values for texture coordinates vdotuA = 0.5 * (1.0 - vdotuA); vdotuB = 0.5 * (1.0 + vdotuB); returnedPoint.SetUV(vdotuA, vdotuB); returnedPoint.SetFaceNumber(TopFaceNum); break; case 1: // Bottom face returnedPoint.SetNormal(BottomNormal); if (returnedPoint.IsFrontFacing()) { returnedPoint.SetMaterial(*BottomOuterMat); } else { returnedPoint.SetMaterial(*BottomInnerMat); } // Calculate U-V values for texture coordinates vdotuA = 0.5 * (1.0 + vdotuA); vdotuB = 0.5 * (1.0 + vdotuB); returnedPoint.SetUV(vdotuA, vdotuB); returnedPoint.SetFaceNumber(BaseFaceNum); break; case 2: // Cylinder's side Vector3 normal; normal = vdotuA * AxisA; normal += vdotuB * AxisB; normal.Normalize(); returnedPoint.SetNormal(normal); if (returnedPoint.IsFrontFacing()) { returnedPoint.SetMaterial(SideOuterMat); } else { returnedPoint.SetMaterial(SideInnerMat); } // Calculate u-v coordinates for texture mapping (in range[0,1]x[0,1]) double uCoord = Math.Atan2(vdotuB, vdotuA) / MathHelper.Tau + 0.5; double vCoord; if (IsRightCylinder()) { vCoord = (Vector3Ex.Dot(v, CenterAxis) + HalfHeight) / Height; } else { Vector3 hitPos = returnedPoint.GetPosition(); double distUp = (TopPlaneCoef - Vector3Ex.Dot(hitPos, TopNormal)) / Vector3Ex.Dot(CenterAxis, TopNormal); double distDown = -(BottomPlaneCoef - Vector3Ex.Dot(hitPos, BottomNormal)) / Vector3Ex.Dot(CenterAxis, BottomNormal); if (distDown + distUp > 0.0) { vCoord = distDown / (distDown + distUp); } else { vCoord = 0.5; // At corner } } returnedPoint.SetUV(uCoord, vCoord); returnedPoint.SetFaceNumber(SideFaceNum); } return(true); }
/// <summary> /// Builds a cylinder into the geometry with correct texture coordinates and normals. /// </summary> /// <param name="target">Target <see cref="GeometrySurface"/>.</param> /// <param name="bottomMiddle">Coordinate of bottom middle.</param> /// <param name="radius">The radius of the cylinder.</param> /// <param name="height">The height of the cylinder.</param> /// <param name="countOfSegments">Total count of segments to generate.</param> /// <param name="buildBottom">Build bottom of the cylinder.</param> /// <param name="buildSides">Build sides of the cylinder.</param> /// <param name="buildTop">Build top side of the cylinder.</param> public static BuiltVerticesRange BuildCylinder( this GeometrySurface target, Vector3 bottomMiddle, float radius, float height, int countOfSegments, bool buildSides, bool buildBottom, bool buildTop) { var startVertex = target.Owner.CountVertices; radius = Math.Max(EngineMath.TOLERANCE_FLOAT_POSITIVE, radius); height = Math.Max(EngineMath.TOLERANCE_FLOAT_POSITIVE, height); countOfSegments = Math.Max(3, countOfSegments); var diameter = radius * 2f; // Get texture offsets var texX = 1f; var texY = 1f; var texSegmentY = 1f; var texSegmentX = 1f; if (target.IsTextureTileModeEnabled(out var tileSize)) { texX = diameter / tileSize.X; texY = diameter / tileSize.Y; texSegmentY = height / tileSize.Y; texSegmentX = EngineMath.RAD_180DEG * diameter / tileSize.X; } // Specify bottom and top middle coordinates var bottomCoordinate = bottomMiddle; var topCoordinate = new Vector3(bottomMiddle.X, bottomMiddle.Y + height, bottomMiddle.Z); // Create bottom and top vertices var bottomVertex = new VertexBasic(bottomCoordinate, new Vector2(texX / 2f, texY / 2f), new Vector3(0f, -1f, 0f)); var topVertex = new VertexBasic(topCoordinate, new Vector2(texX / 2f, texY / 2f), new Vector3(0f, 1f, 0f)); // AddObject bottom and top vertices to the geometry var bottomVertexIndex = target.Owner.AddVertex(bottomVertex); var topVertexIndex = target.Owner.AddVertex(topVertex); // Generate all segments var fullRadian = EngineMath.RAD_360DEG; var countOfSegmentsF = (float)countOfSegments; for (var loop = 0; loop < countOfSegments; loop++) { // Calculate rotation values for each segment border var startRadian = fullRadian * (loop / countOfSegmentsF); var targetRadian = fullRadian * ((loop + 1) / countOfSegmentsF); var normalRadian = startRadian + (targetRadian - startRadian) / 2f; // Generate all normals var sideNormal = Vector3Ex.NormalFromHVRotation(normalRadian, 0f); var sideLeftNormal = Vector3Ex.NormalFromHVRotation(startRadian, 0f); var sideRightNormal = Vector3Ex.NormalFromHVRotation(targetRadian, 0f); // var sideLeftTexCoord = new Vector2(0.5f + sideLeftNormal.X * radius, 0.5f + sideLeftNormal.Z * radius); var sideRightTexCoord = new Vector2(0.5f + sideRightNormal.X * radius, 0.5f + sideRightNormal.Z * radius); // Generate all points var sideLeftBottomCoord = bottomCoordinate + sideLeftNormal * radius; var sideRightBottomCoord = bottomCoordinate + sideRightNormal * radius; var sideLeftTopCoord = new Vector3(sideLeftBottomCoord.X, sideLeftBottomCoord.Y + height, sideLeftBottomCoord.Z); var sideRightTopCoord = new Vector3(sideRightBottomCoord.X, sideRightBottomCoord.Y + height, sideRightBottomCoord.Z); // AddObject segment bottom triangle if (buildBottom) { var segmentBottomLeft = bottomVertex.Copy(sideLeftBottomCoord, sideLeftTexCoord); var segmentBottomRight = bottomVertex.Copy(sideRightBottomCoord, sideRightTexCoord); target.AddTriangle( bottomVertexIndex, target.Owner.AddVertex(segmentBottomLeft), target.Owner.AddVertex(segmentBottomRight)); } // AddObject segment top triangle if (buildTop) { var segmentTopLeft = topVertex.Copy(sideLeftTopCoord, sideLeftTexCoord); var segmentTopRight = topVertex.Copy(sideRightTopCoord, sideRightTexCoord); target.AddTriangle( topVertexIndex, target.Owner.AddVertex(segmentTopRight), target.Owner.AddVertex(segmentTopLeft)); } if (buildSides) { // Calculate texture coords for side segment var texCoordSegmentStart = new Vector2(texSegmentX * (loop / (float)countOfSegments), 0f); var texCoordSegmentTarget = new Vector2(texSegmentX * ((loop + 1) / (float)countOfSegments), texSegmentY); // AddObject segment side target.BuildRect(sideLeftBottomCoord, sideRightBottomCoord, sideRightTopCoord, sideLeftTopCoord, sideNormal, texCoordSegmentStart, texCoordSegmentTarget); } } return(new BuiltVerticesRange(target.Owner, startVertex, target.Owner.CountVertices - startVertex)); }
public override void OnKilled(HitInfo info) { if (base.isClient) { return; } this.CreateExplosionMarker(10f); Effect.server.Run(this.explosionEffect.resourcePath, base.transform.position, Vector3.up, null, true); Vector3 lastMoveDir = (this.myAI.GetLastMoveDir() * this.myAI.GetMoveSpeed()) * 0.75f; GameObject component = this.servergibs.Get().GetComponent <ServerGib>()._gibSource; List <ServerGib> serverGibs = ServerGib.CreateGibs(this.servergibs.resourcePath, base.gameObject, component, lastMoveDir, 3f); for (int i = 0; i < 12 - this.maxCratesToSpawn; i++) { BaseEntity vector3 = GameManager.server.CreateEntity(this.fireBall.resourcePath, base.transform.position, base.transform.rotation, true); if (vector3) { float single = 3f; float single1 = 10f; Vector3 vector31 = UnityEngine.Random.onUnitSphere; vector3.transform.position = (base.transform.position + new Vector3(0f, 1.5f, 0f)) + (vector31 * UnityEngine.Random.Range(-4f, 4f)); Collider collider = vector3.GetComponent <Collider>(); vector3.Spawn(); vector3.SetVelocity(lastMoveDir + (vector31 * UnityEngine.Random.Range(single, single1))); foreach (ServerGib serverGib in serverGibs) { Physics.IgnoreCollision(collider, serverGib.GetCollider(), true); } } } for (int j = 0; j < this.maxCratesToSpawn; j++) { Vector3 vector32 = UnityEngine.Random.onUnitSphere; Vector3 vector33 = (base.transform.position + new Vector3(0f, 1.5f, 0f)) + (vector32 * UnityEngine.Random.Range(2f, 3f)); BaseEntity baseEntity = GameManager.server.CreateEntity(this.crateToDrop.resourcePath, vector33, Quaternion.LookRotation(vector32), true); baseEntity.Spawn(); LootContainer lootContainer = baseEntity as LootContainer; if (lootContainer) { lootContainer.Invoke(new Action(lootContainer.RemoveMe), 1800f); } Collider component1 = baseEntity.GetComponent <Collider>(); Rigidbody rigidbody = baseEntity.gameObject.AddComponent <Rigidbody>(); rigidbody.useGravity = true; rigidbody.collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic; rigidbody.mass = 2f; rigidbody.interpolation = RigidbodyInterpolation.Interpolate; rigidbody.velocity = lastMoveDir + (vector32 * UnityEngine.Random.Range(1f, 3f)); rigidbody.angularVelocity = Vector3Ex.Range(-1.75f, 1.75f); rigidbody.drag = 0.5f * (rigidbody.mass / 5f); rigidbody.angularDrag = 0.2f * (rigidbody.mass / 5f); GameManager gameManager = GameManager.server; string str = this.fireBall.resourcePath; Vector3 vector34 = new Vector3(); Quaternion quaternion = new Quaternion(); FireBall fireBall = gameManager.CreateEntity(str, vector34, quaternion, true) as FireBall; if (fireBall) { fireBall.SetParent(baseEntity, false, false); fireBall.Spawn(); fireBall.GetComponent <Rigidbody>().isKinematic = true; fireBall.GetComponent <Collider>().enabled = false; } baseEntity.SendMessage("SetLockingEnt", fireBall.gameObject, SendMessageOptions.DontRequireReceiver); foreach (ServerGib serverGib1 in serverGibs) { Physics.IgnoreCollision(component1, serverGib1.GetCollider(), true); } } base.OnKilled(info); }