internal static bool AreEqual(ITestOutputHelper testOutputHelper, Type sourceType, Type targetType, CastResult compilerResult, CastResult castResult, CastFlag expectedCastFlag) { if (compilerResult.IsSuccessful == true && castResult.IsSuccessful == false) { // Let's assert the details if the compiler generates a successful result // but the CastTo method does not the same. var castFlagsAreEqual = compilerResult.CastFlag == castResult.CastFlag || castResult.CastFlag == CastFlag.Implicit; if (!castFlagsAreEqual) { testOutputHelper.WriteLine("CastFlags of conversion between {0} and {1} are not equal." + Environment.NewLine + "Expected CastFlag: {2}" + Environment.NewLine + "Resulted CastFlag: {3}" + Environment.NewLine, sourceType.GetFormattedName(), targetType.GetFormattedName(), expectedCastFlag, castResult.CastFlag); return false; } var valuesAreNotEqual = compilerResult.CastFlag == castResult.CastFlag && !Equals(compilerResult.Value, castResult.Value); if (valuesAreNotEqual) { testOutputHelper.WriteLine("Result of {0} conversion between {1} and {2} are not equal.", expectedCastFlag == CastFlag.Implicit ? "implicit" : "explicit", sourceType.GetFormattedName(), targetType.GetFormattedName()); return false; } } return true; }
private void HandleCasting() { if (Input.GetKeyDown(KeyCode.Space) && preparing == false && casting == false) { preparing = true; if (spellbookScroller.activeSelf == true) { spellbookScroller.SetActive(false); spellBookController.gameObject.SetActive(false); } componentLoader.GatherComponents(spellBook[currentSpell].components); } else if (casting) { castTicker += Time.deltaTime; if (castTicker > castSpeed) { castTicker = 0; ConsumeMana(WorldObject.CASTING_COST); CastResult res = spellBook[currentSpell].CastNext(); //Debug.Log(res.storedMagic); if (res.storedMagic > channelLimit) { HandleAberration("GandalfOverflowAberration!", res.storedMagic); } else if (res.aberration != "") { HandleAberration(res.aberration, res.storedMagic); } else { if (spellBook[currentSpell].currentLine == -1) { casting = false; } else { voice.Speak(spellBook[currentSpell].SpeakNext(), castSpeed); } } } } }
/// <summary> /// Handle movement along the ground axis. /// </summary> /// <param name="body"></param> /// <param name="direction"></param> /// <param name="filter"></param> /// <param name="results"></param> /// <param name="skinWidth"></param> protected void CastAndMove(Rigidbody2D body, Vector2 direction, ContactFilter2D filter, List <RaycastHit2D> results, float skinWidth, int maxIterations) { //--------------------------------------------------------------------------------------------------------- // Add startup code here before the iteration. //--------------------------------------------------------------------------------------------------------- Vector2 currentPosition = body.position; Vector2 currentDirection = direction; Vector2 targetPosition = currentPosition + currentDirection; int i = 0; while (i < maxIterations) { //--------------------------------------------------------------------------------------------------------- // The collision detection stage consists of casting the body in the given direction and length and // recieving the result in a CastResult structure. The length takes into account the // contact Offset/skinwidth. We then update the characters current position. //--------------------------------------------------------------------------------------------------------- CastResult hit = CollisionDetection(body, currentDirection, filter, results, skinWidth); currentPosition += currentDirection.normalized * hit.Distance; //--------------------------------------------------------------------------------------------------------- // The collision response stage consists of calculating a new target position from the hit recieved from // the collision detection stage. From the hit we calculate a new direction //--------------------------------------------------------------------------------------------------------- targetPosition = CollisionResponse(currentPosition, targetPosition, hit.Normal, 0, 0); currentDirection = targetPosition - currentPosition; //--------------------------------------------------------------------------------------------------------- // At the end of the iteration we move the character's body to the current position. In the next iteration, // we'll move the character towards the deflected position we got from this iteration //--------------------------------------------------------------------------------------------------------- body.position = currentPosition; i++; } //--------------------------------------------------------------------------------------------------------- // Before we exit the method we make sure the character is sent to the right position. //--------------------------------------------------------------------------------------------------------- body.position = currentPosition; }
/// <summary> /// Raycast to forward /// </summary> private void CastToForward() { //Origin position of ray cast Vector3 l_originCastPosition = transform.position + transform.forward * originDistance; //Make raycast from origin position to forward CastResult l_castResult = SMCast.RayCast(this, l_originCastPosition, transform.forward, castDistance); //Did raycast hit something? => Paint the target if (l_castResult) { //Get first casted game object (In the simple ray cast it only one) GameObject l_castedGameObject = l_castResult.GetFirstHit().collider.gameObject; //Change color of material on casted game object PaintCastTarget(l_castedGameObject, Color.white); } }
/// <summary> /// Cancel cast with supplied <see cref="CastResult"/>. /// </summary> public void CancelCast(CastResult result) { if (status != SpellStatus.Casting) { throw new InvalidOperationException(); } if (caster is Player player && !player.IsLoading) { player.Session.EnqueueMessageEncrypted(new Server07F9 { ServerUniqueId = CastingId, CastResult = result, CancelCast = true }); } events.CancelEvents(); status = SpellStatus.Executing; log.Trace($"Spell {parameters.SpellInfo.Entry.Id} cast was cancelled."); }
private CastResult CheckCast() { CastResult preReqCheck = CheckPrerequisites(); if (preReqCheck != CastResult.Ok) { return(preReqCheck); } CastResult ccResult = CheckCCConditions(); if (ccResult != CastResult.Ok) { return(ccResult); } if (caster is Player player) { if (player.SpellManager.GetSpellCooldown(parameters.SpellInfo.Entry.Id) > 0d) { return(CastResult.SpellCooldown); } // this isn't entirely correct, research GlobalCooldownEnum if (parameters.SpellInfo.Entry.GlobalCooldownEnum == 0 && player.SpellManager.GetGlobalSpellCooldown() > 0d) { return(CastResult.SpellGlobalCooldown); } if (parameters.CharacterSpell?.MaxAbilityCharges > 0 && parameters.CharacterSpell?.AbilityCharges == 0) { return(CastResult.SpellNoCharges); } } return(CastResult.Ok); }
private void Update() { float extrapolatedDistance = (direction * Time.deltaTime * speed).magnitude; Vector3 extrapolatedPosition = transform.position + direction * extrapolatedDistance; CastResult castResult = Cast(direction, extrapolatedDistance, transform.position); if (castResult.SomethingHit) { direction = castResult.ReflectedDirection; if (castResult.FoundCell != null) { World.DefaultGameObjectInjectionWorld.EntityManager.AddComponentData(castResult.FoundCell.Entity, new SpawnBubbleCmp() { SolveHere = true, RandomizeNumber = false, Number = number }); World.DefaultGameObjectInjectionWorld.EntityManager.AddComponentData(bubbleIsShootingTagEntity, new DestroyTagCmp()); Destroy(gameObject); } if (extrapolatedDistance > Vector3.Distance(transform.position, castResult.ContactPoint)) { transform.position = castResult.ContactPoint; } else { transform.position = extrapolatedPosition; } } else { transform.position = extrapolatedPosition; } }
internal static bool AreEqual(ITestOutputHelper testOutputHelper, Type sourceType, Type targetType, CastResult compilerResult, CastResult castResult, CastFlag expectedCastFlag) { if (compilerResult.IsSuccessful == true && castResult.IsSuccessful == false) { // Let's assert the details if the compiler generates a successful result // but the CastTo method does not the same. var castFlagsAreEqual = compilerResult.CastFlag == castResult.CastFlag || castResult.CastFlag == CastFlag.Implicit; if (!castFlagsAreEqual) { testOutputHelper.WriteLine("CastFlags of conversion between {0} and {1} are not equal." + Environment.NewLine + "Expected CastFlag: {2}" + Environment.NewLine + "Resulted CastFlag: {3}" + Environment.NewLine, sourceType.GetFormattedName(), targetType.GetFormattedName(), expectedCastFlag, castResult.CastFlag); return(false); } var valuesAreNotEqual = compilerResult.CastFlag == castResult.CastFlag && !Equals(compilerResult.Value, castResult.Value); if (valuesAreNotEqual) { testOutputHelper.WriteLine("Result of {0} conversion between {1} and {2} are not equal.", expectedCastFlag == CastFlag.Implicit ? "implicit" : "explicit", sourceType.GetFormattedName(), targetType.GetFormattedName()); return(false); } } return(true); }
public static bool Cast(Vector3 startPoint, Vector3 direction, float maxDistance, Func <Int3, bool> checkMethod, out CastResult result) { direction = direction.normalized; var t = 0f; var ix = Mathf.FloorToInt(startPoint.x); var iy = Mathf.FloorToInt(startPoint.y); var iz = Mathf.FloorToInt(startPoint.z); var stepX = (int)Mathf.Sign(direction.x); var stepY = (int)Mathf.Sign(direction.y); var stepZ = (int)Mathf.Sign(direction.z); var txDelta = Mathf.Abs(1 / direction.x); var tyDelta = Mathf.Abs(1 / direction.y); var tzDelta = Mathf.Abs(1 / direction.z); var xDist = (stepX > 0) ? (ix + 1 - startPoint.x) : (startPoint.x - ix); var yDist = (stepY > 0) ? (iy + 1 - startPoint.y) : (startPoint.y - iy); var zDist = (stepZ > 0) ? (iz + 1 - startPoint.z) : (startPoint.z - iz); var txMax = (txDelta < Mathf.Infinity) ? txDelta * xDist : Mathf.Infinity; var tyMax = (tyDelta < Mathf.Infinity) ? tyDelta * yDist : Mathf.Infinity; var tzMax = (tzDelta < Mathf.Infinity) ? tzDelta * zDist : Mathf.Infinity; var steppedIndex = -1; var res = new CastResult(); while (t < maxDistance) { var isSolid = checkMethod(new Int3(ix, iy, iz)); if (isSolid) { var point = startPoint + new Vector3(t * direction.x, t * direction.y, t * direction.z); res.HitPosition = point; if (steppedIndex == 0) { res.Normal = new Vector3(-stepX, 0, 0); } if (steppedIndex == 1) { res.Normal = new Vector3(0, -stepY, 0); } if (steppedIndex == 2) { res.Normal = new Vector3(0, 0, -stepZ); } result = res; return(true); } if (txMax < tyMax) { if (txMax < tzMax) { ix += stepX; t = txMax; txMax += txDelta; steppedIndex = 0; } else { iz += stepZ; t = tzMax; tzMax += tzDelta; steppedIndex = 2; } } else { if (tyMax < tzMax) { iy += stepY; t = tyMax; tyMax += tyDelta; steppedIndex = 1; } else { iz += stepZ; t = tzMax; tzMax += tzDelta; steppedIndex = 2; } } } result = res; return(false); }
/// cast a convex against another convex object internal override bool calcTimeOfImpact( ref btTransform fromA, ref btTransform toA, ref btTransform fromB, ref btTransform toB, CastResult result) { m_simplexSolver.reset(); /// compute linear velocity for this interval, to interpolate //assume no rotation/angular velocity, assert here? btVector3 linVelA, linVelB; toA.m_origin.Sub( ref fromA.m_origin, out linVelA ); toB.m_origin.Sub( ref fromB.m_origin, out linVelB ); double radius = (double)( 0.001 ); double lambda = btScalar.BT_ZERO; btVector3 v = btVector3.xAxis; int maxIter = MAX_ITERATIONS; btVector3 n = btVector3.Zero; bool hasResult = false; btVector3 c; btVector3 r; linVelA.Sub( ref linVelB, out r ); double lastLambda = lambda; //double epsilon = (double)(0.001); int numIter = 0; //first solution, using GJK // result.drawCoordSystem(sphereTr); btPointCollector pointCollector = new btPointCollector(); btGjkPairDetector gjk = BulletGlobals.GjkPairDetectorPool.Get(); gjk.Initialize( m_convexA, m_convexB, m_simplexSolver, null);//m_penetrationDepthSolver); btGjkPairDetector.ClosestPointInput input = new btDiscreteCollisionDetectorInterface.ClosestPointInput(); //we don't use margins during CCD // gjk.setIgnoreMargin(true); input.m_transformA = fromA.T; input.m_transformB = fromB.T; gjk.getClosestPoints( input, pointCollector, null ); hasResult = pointCollector.m_hasResult; c = pointCollector.m_pointInWorld; if( hasResult ) { double dist; dist = pointCollector.m_distance; n = pointCollector.m_normalOnBInWorld; //not close enough while( dist > radius ) { numIter++; if( numIter > maxIter ) { BulletGlobals.GjkPairDetectorPool.Free( gjk ); return false; //todo: report a failure } double dLambda = btScalar.BT_ZERO; double projectedLinearVelocity = r.dot( ref n ); dLambda = dist / ( projectedLinearVelocity ); lambda = lambda - dLambda; if( lambda > btScalar.BT_ONE ) { BulletGlobals.GjkPairDetectorPool.Free( gjk ); return false; } if( lambda < btScalar.BT_ZERO ) { BulletGlobals.GjkPairDetectorPool.Free( gjk ); return false; } //todo: next check with relative epsilon if( lambda <= lastLambda ) { BulletGlobals.GjkPairDetectorPool.Free( gjk ); return false; //n.setValue(0,0,0); //break; } lastLambda = lambda; //interpolate to next lambda result.DebugDraw( lambda ); btVector3 tmp; btVector3.setInterpolate3( out tmp, ref fromA.m_origin, ref toA.m_origin, lambda ); input.m_transformA.setOrigin( ref tmp ); btVector3.setInterpolate3( out tmp, ref fromB.m_origin, ref toB.m_origin, lambda ); input.m_transformB.setOrigin( ref tmp ); gjk.getClosestPoints( input, pointCollector, null ); if( pointCollector.m_hasResult ) { if( pointCollector.m_distance < btScalar.BT_ZERO ) { result.m_fraction = lastLambda; n = pointCollector.m_normalOnBInWorld; result.m_normal = n; result.m_hitPoint = pointCollector.m_pointInWorld; BulletGlobals.GjkPairDetectorPool.Free( gjk ); return true; } c = pointCollector.m_pointInWorld; n = pointCollector.m_normalOnBInWorld; dist = pointCollector.m_distance; } else { //?? BulletGlobals.GjkPairDetectorPool.Free( gjk ); return false; } } //is n normalized? //don't report time of impact for motion away from the contact normal (or causes minor penetration) if( n.dot( ref r ) >= -result.m_allowedPenetration ) { BulletGlobals.GjkPairDetectorPool.Free( gjk ); return false; } result.m_fraction = lambda; result.m_normal = n; result.m_hitPoint = c; BulletGlobals.GjkPairDetectorPool.Free( gjk ); return true; } BulletGlobals.GjkPairDetectorPool.Free( gjk ); return false; }
public bool CalcTimeOfImpact(Matrix fromA, Matrix toA, Matrix fromB, Matrix toB, CastResult result) { return(btConvexCast_calcTimeOfImpact(_native, ref fromA, ref toA, ref fromB, ref toB, result._native)); }
protected virtual void onCast(CastResult result, TypeOfResources resource = TypeOfResources.Nothing) { }
public static IEnumerable <Cast> ToModel(this CastResult castList) { return(castList.Cast.Select(x => x.ToModel())); }
internal override bool calcTimeOfImpact( ref btTransform fromA, ref btTransform toA, ref btTransform fromB, ref btTransform toB, CastResult result) { /// compute linear and angular velocity for this interval, to interpolate btVector3 linVelA, angVelA, linVelB, angVelB; btTransformUtil.calculateVelocity( ref fromA,ref toA, btScalar.BT_ONE, out linVelA, out angVelA ); btTransformUtil.calculateVelocity( ref fromB, ref toB, btScalar.BT_ONE, out linVelB, out angVelB ); double boundingRadiusA = m_convexA.getAngularMotionDisc(); double boundingRadiusB = m_convexB1 != null ? m_convexB1.getAngularMotionDisc() : 0; double maxAngularProjectedVelocity = angVelA.length() * boundingRadiusA + angVelB.length() * boundingRadiusB; btVector3 relLinVel = ( linVelB - linVelA ); double relLinVelocLength = btVector3.btDelLength( ref linVelB,ref linVelA ); if( ( relLinVelocLength + maxAngularProjectedVelocity ) == 0 ) return false; double lambda = btScalar.BT_ZERO; btVector3 v = btVector3.xAxis; int maxIter = MAX_ITERATIONS; btVector3 n = btVector3.Zero; bool hasResult = false; btVector3 c; double lastLambda = lambda; //double epsilon = (double)(0.001); int numIter = 0; //first solution, using GJK double radius = 0.001f; // result.drawCoordSystem(sphereTr); btPointCollector pointCollector1 = new btPointCollector(); { computeClosestPoints( ref fromA, ref fromB, pointCollector1 ); hasResult = pointCollector1.m_hasResult; c = pointCollector1.m_pointInWorld; } if( hasResult ) { double dist; dist = pointCollector1.m_distance + result.m_allowedPenetration; n = pointCollector1.m_normalOnBInWorld; double projectedLinearVelocity = relLinVel.dot( n ); if( ( projectedLinearVelocity + maxAngularProjectedVelocity ) <= btScalar.SIMD_EPSILON ) return false; //not close enough while( dist > radius ) { if( result.m_debugDrawer != null ) { result.m_debugDrawer.drawSphere( ref c, 0.2f, ref btVector3.One ); } double dLambda = btScalar.BT_ZERO; projectedLinearVelocity = relLinVel.dot( n ); //don't report time of impact for motion away from the contact normal (or causes minor penetration) if( ( projectedLinearVelocity + maxAngularProjectedVelocity ) <= btScalar.SIMD_EPSILON ) return false; dLambda = dist / ( projectedLinearVelocity + maxAngularProjectedVelocity ); lambda = lambda + dLambda; if( lambda > btScalar.BT_ONE ) return false; if( lambda < btScalar.BT_ZERO ) return false; //todo: next check with relative epsilon if( lambda <= lastLambda ) { return false; } lastLambda = lambda; //interpolate to next lambda btTransform interpolatedTransA, interpolatedTransB, relativeTrans; btTransformUtil.integrateTransform( ref fromA, ref linVelA, ref angVelA, lambda, out interpolatedTransA ); btTransformUtil.integrateTransform( ref fromB, ref linVelB, ref angVelB, lambda, out interpolatedTransB ); interpolatedTransB.inverseTimes( ref interpolatedTransA, out relativeTrans ); if( result.m_debugDrawer != null ) { result.m_debugDrawer.drawSphere( ref interpolatedTransA.m_origin, 0.2f, ref btVector3.xAxis ); } result.DebugDraw( lambda ); btPointCollector pointCollector = new btPointCollector(); computeClosestPoints( ref interpolatedTransA, ref interpolatedTransB, pointCollector ); if( pointCollector.m_hasResult ) { dist = pointCollector.m_distance + result.m_allowedPenetration; c = pointCollector.m_pointInWorld; n = pointCollector.m_normalOnBInWorld; } else { result.reportFailure( -1, numIter ); return false; } numIter++; if( numIter > maxIter ) { result.reportFailure( -2, numIter ); return false; } } result.m_fraction = lambda; result.m_normal = n; result.m_hitPoint = c; return true; } return false; }
public static Cast Map(CastResult source) => Mapper.Map <Cast>(source);
private IEnumerator ShootLineRoutine() { while (true) { if (GameManager.Initialized == false) { yield return(null); continue; } //if (!Input.GetMouseButton(1)) //{ // yield return null; // continue; //} Vector3 mouseWorldPosition = cameraBounds.Cam.ScreenToWorldPoint(Input.mousePosition); Vector3 position = new Vector3(mouseWorldPosition.x, mouseWorldPosition.y, 0); Vector3 normalToTarget = (position - pivot.position).normalized; List <Vector3> points = new List <Vector3>(); Quaternion desiredRotation = Quaternion.LookRotation(Vector3.forward, normalToTarget); float zAngle = Vector3.SignedAngle(Vector3.up, normalToTarget, Vector3.forward); zAngle = Mathf.Clamp(zAngle, -60, 60); Quaternion clampedRotation = Quaternion.Euler(desiredRotation.eulerAngles.x, desiredRotation.eulerAngles.y, zAngle); pivot.rotation = clampedRotation; Vector3 cannonDirection = clampedRotation * Vector3.up; Vector3 currentRayPosition = shootPoint.position; Vector3 currentRayDirection = cannonDirection; points.Add(currentRayPosition); yield return(null); bool exitLoop = false; canShoot = false; while (!exitLoop) { CastResult castResult = PhysicsEx.Cast(currentRayDirection, float.MaxValue, currentRayPosition); if (castResult.SomethingHit) { currentRayPosition = castResult.ContactPoint; currentRayDirection = castResult.ReflectedDirection; if (castResult.FinalObjectHit) { exitLoop = true; } if (castResult.FoundCell != null) { CellCmp cellCmp = World.DefaultGameObjectInjectionWorld.EntityManager.GetComponentData <CellCmp>(castResult.FoundCell.Entity); if (cellCmp.IsEmpty) { canShoot = true; circle.transform.position = castResult.FoundCell.transform.position; circle.transform.localScale = Vector3.one * GameManager.CellDiameter; } } points.Add(currentRayPosition); } else { exitLoop = true; } } circle.gameObject.SetActive(canShoot); shootLine.positionCount = points.Count; for (int i = 0; i < points.Count; i++) { shootLine.SetPosition(i, points[i]); if (i + 1 < points.Count) { Debug.DrawLine(points[i], points[i + 1], Color.red); } } shootLine.startColor = shootLine.endColor = canShoot ? Color.green : Color.red; yield return(null); if (spawnBubble) { ShootingBubble spawnedBubble = Instantiate(shootingBubblePrefab, shootPoint.position, Quaternion.identity, null); spawnedBubble.transform.localScale = Vector3.one * GameManager.CellDiameter; spawnedBubble.SetNumber(nextNumber); spawnedBubble.SetDirection(cannonDirection); spawnBubble = false; PreloadNextNumber(); } } }
internal static CastResult CastTo(object value, Type targetType) { if (value == null) { return(new CastResult((object)null, CastFlag.Undefined)); } Guard.ArgumentNotNull(targetType, nameof(targetType)); var sourceType = value.GetType(); var sourceTypeInfo = value.GetType().GetTypeInfo(); var targetTypeInfo = targetType.GetTypeInfo(); if (targetTypeInfo.IsGenericType && !targetTypeInfo.GenericTypeArguments.Any()) { return (new CastResult( ConversionNotSupportedException.Create( sourceType, targetType, string.Format("The target type {0} does not have sufficient generic type arguments specified.", targetType.GetFormattedName())), CastFlag.Undefined)); } CastResult castResult = null; CastFlag castFlag = CastFlag.Undefined; try { // explicit conversion always works if to : from OR if there's an implicit conversion if (targetType.IsSameOrParent(sourceType)) { castFlag = CastFlag.Implicit; var castedValue = GenericCast(() => AttemptImplicitCast <object, object>(null), sourceType, targetType, value); castResult = new CastResult(castedValue, castFlag); } // for nullable types, we can simply strip off the nullability and evaluate the underyling types else if (Nullable.GetUnderlyingType(targetType) != null) { castResult = CastTo(value, Nullable.GetUnderlyingType(targetType)); } else if (sourceTypeInfo.IsValueType) { castFlag = CastFlag.Explicit; var castedValue = GenericCast(() => AttemptExplicitCast <object, object>(null), sourceType, targetType, value); castResult = new CastResult(castedValue, castFlag); } else { // Implicit cast operators have priority in favour of explicit operators // since they should not lose precision. See C# language specification: // https://msdn.microsoft.com/en-us/library/z5z9kes2.aspx var conversionMethods = GetCastOperatorMethods(sourceType, targetType) .OrderByDescending(m => m.Name == "op_Implicit") .ThenByDescending(m => m.ReturnType == targetType || m.ReturnType.GetTypeInfo().IsAssignableFrom(targetTypeInfo)); foreach (var conversionMethod in conversionMethods) { try { var convertedValue = conversionMethod.Invoke(null, new[] { value }); castResult = CastTo(convertedValue, targetType); if (castResult.IsSuccessful) { break; } else { castResult = null; } } catch { } } } } catch (Exception ex) { castResult = new CastResult(ConversionNotSupportedException.Create(sourceType, targetType, ex.InnerException), castFlag); } if (castResult == null) { castResult = new CastResult(ConversionNotSupportedException.Create(sourceType, targetType), castFlag); } return(castResult); }
// Update is called once per frame void Update() { lr.SetPosition(0, transform.position); lr.SetPosition(1, transform.position + transform.forward * showDistance); SteamVR_Controller.Device device = SteamVR_Controller.Input((int)trackedObj.index); if (device.GetPress(SteamVR_Controller.ButtonMask.Touchpad)) { Vector2 pad = device.GetAxis(); Vector3 cross = Vector3.Cross(new Vector2(1, 0), pad); float angle = Vector2.Angle(new Vector2(1, 0), pad); float ang = cross.z > 0 ? -angle : angle; Debug.Log(ang); if (ang > 0 && ang < 180) { Debug.Log("down"); if (res.resultObj != null) { res.resultObj.transform.Translate(-transform.forward * Time.deltaTime * 5, Space.World); } } else if (ang < 0 && ang > -180) { Debug.Log("up"); if (res.resultObj != null) { res.resultObj.transform.Translate(transform.forward * Time.deltaTime * 5, Space.World); } //obj.transform.Translate(Vector3.forward * Time.deltaTime * 5); } // if (ang > 45 && ang < 135) // { // Debug.Log("down"); // //obj.transform.Translate(Vector3.back * Time.deltaTime * 5); // } // else if (ang < -45 && ang> -135) // { // Debug.Log("up"); // //obj.transform.Translate(Vector3.forward * Time.deltaTime * 5); // } // else if ((ang < 180 && ang> 135) || (ang < -135 && ang > -180)) // { // Debug.Log("left"); // //obj.transform.Rotate(Vector3.up * Time.deltaTime * -25); // } // else if ((ang > 0 && ang< 45) || (ang > -45 && ang< 0)){ // Debug.Log("right"); // } } if (device.GetPressDown(SteamVR_Controller.ButtonMask.Trigger)) { if (setLock == false) { res = testCast(); if (res.castable != false) { res.resultObj.transform.position = transform.position + transform.forward * distance; res.resultObj.transform.SetParent(transform); //Destroy(res.resultObj.GetComponent<BuoyancyApplier>()); res.resultObj.GetComponent <BuoyancyApplier>().enabled = false; rb = res.resultObj.GetComponent <Rigidbody>(); rb.useGravity = false; //srb.mass = rb.mass; //srb.drag = rb.drag; //srb.angularDrag = rb.angularDrag; //srb.useGravity = rb.useGravity; //Destroy(res.resultObj.GetComponent<Rigidbody>()); setLock = true; } } else { if (res.resultObj != null) { res.resultObj.transform.parent = null; //res.resultObj.AddComponent<Rigidbody>(); rb = res.resultObj.GetComponent <Rigidbody>(); rb.useGravity = true; //rb = res.resultObj.GetComponent<Rigidbody>(); //rb.mass = srb.mass ; //rb.drag = srb.drag ; //rb.angularDrag = srb.angularDrag; //rb.useGravity = srb.useGravity; // res.resultObj.AddComponent<BuoyancyApplier>(); res.resultObj.GetComponent <BuoyancyApplier>().enabled = true; setLock = false; } } } // if(device.GetPressUp(SteamVR_Controller.ButtonMask.Trigger)){ // if(res.resultObj != null){ // res.resultObj.transform.parent = null; // } // // res = testCast(); // // if(res.castable != false){ // // res.resultObj.transform.position = transform.position + transform.forward * distance; // // } // } }
public SpherecastInfo(Ray ray, float radius, float maxDistance, bool castAll, CastResult castResult) { OriginPoint = ray.origin; Direction = ray.direction; MaxDistance = maxDistance; CastResult = castResult; CastAll = castAll; Radius = radius; }
/// cast a convex against another convex object internal abstract bool calcTimeOfImpact( ref btTransform fromA, ref btTransform toA, ref btTransform fromB, ref btTransform toB, CastResult result );
public BoxcastInfo(Ray ray, Vector3 size, Quaternion rotation, float maxDistance, bool castAll, CastResult castResult) { OriginPoint = ray.origin; Direction = ray.direction; CastResult = castResult; Size = size; MaxDistance = maxDistance; CastAll = castAll; Rotation = rotation; }
public bool CalcTimeOfImpact(Matrix fromA, Matrix toA, Matrix fromB, Matrix toB, CastResult result) { return btConvexCast_calcTimeOfImpact(_native, ref fromA, ref toA, ref fromB, ref toB, result._native); }
private void _CastResult(CastResult cast_result) { if (cast_result == CastResult.Hit || cast_result == CastResult.Miss) IdleEvent(); }
protected override void onCast(CastResult result, TypeOfResources resource = TypeOfResources.Nothing) { base.onCast(result, resource); }
///SimsimplexConvexCast calculateTimeOfImpact calculates the time of impact+normal for the linear cast (sweep) between two moving objects. ///Precondition is that objects should not penetration/overlap at the start from the interval. Overlap can be tested using btGjkPairDetector. /// ///Typically the conservative advancement reaches solution in a few iterations, clip it to 32 for degenerate cases. ///See discussion about this here http://continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=565 internal override bool calcTimeOfImpact( ref btTransform fromA, ref btTransform toA, ref btTransform fromB, ref btTransform toB, CastResult result ) { m_simplexSolver.reset(); btVector3 linVelA, linVelB; toA.m_origin.Sub( ref fromA.m_origin, out linVelA ); toB.m_origin.Sub( ref fromB.m_origin, out linVelB ); double lambda = btScalar.BT_ZERO; btTransform interpolatedTransA; fromA.Get( out interpolatedTransA ); btTransform interpolatedTransB; fromB.Get( out interpolatedTransB ); ///take relative motion btVector3 r; linVelA.Sub( ref linVelB, out r ); btVector3 v; btVector3 tmp; btVector3 tmp2; r.Invert( out v ); fromA.m_basis.ApplyInverse( ref v, out tmp ); m_convexA.localGetSupportingVertex( ref tmp, out tmp2 ); btVector3 supVertexA; fromA.Apply( ref tmp2, out supVertexA ); //btVector3 supVertexA = fromA( m_convexA.localGetSupportingVertex( -r * fromA.getBasis() ) ); fromB.m_basis.ApplyInverse( ref r, out tmp ); m_convexB.localGetSupportingVertex( ref tmp, out tmp2 ); btVector3 supVertexB; fromB.Apply( ref tmp2, out supVertexB ); //btVector3 supVertexB = fromB( m_convexB.localGetSupportingVertex( r * fromB.getBasis() ) ); supVertexA.Sub( ref supVertexB, out v ); //v = supVertexA - supVertexB; int maxIter = MAX_ITERATIONS; btVector3 n = btVector3.Zero; //btVector3 c; double dist2 = v.length2(); btVector3 w; double VdotR; while( ( dist2 > btScalar.SIMD_LARGE_EPSILON ) && ( maxIter-- != 0 ) ) { //btVector3 tmp, tmp2; v.Invert( out tmp ); interpolatedTransA.m_basis.ApplyInverse( ref tmp, out tmp2 ); m_convexA.localGetSupportingVertex( ref tmp2, out tmp ); interpolatedTransA.Apply( ref tmp, out supVertexA ); //supVertexA = interpolatedTransA( m_convexA.localGetSupportingVertex( -v * interpolatedTransA.getBasis() ) ); interpolatedTransB.m_basis.ApplyInverse( ref v, out tmp2 ); m_convexB.localGetSupportingVertex( ref tmp2, out tmp ); interpolatedTransB.Apply( ref tmp, out supVertexB ); //supVertexB = interpolatedTransB( m_convexB.localGetSupportingVertex( v * interpolatedTransB.getBasis() ) ); supVertexA.Sub( ref supVertexB, out w ); //w = supVertexA - supVertexB; double VdotW = v.dot( ref w ); if( lambda > (double)( 1.0 ) ) { return false; } if( VdotW > btScalar.BT_ZERO ) { VdotR = v.dot( ref r ); if( VdotR >= -( btScalar.SIMD_EPSILON * btScalar.SIMD_EPSILON ) ) return false; else { lambda = lambda - VdotW / VdotR; //interpolate to next lambda // x = s + lambda * r; interpolatedTransA.m_origin.setInterpolate3( ref fromA.m_origin, ref toA.m_origin, lambda ); interpolatedTransB.m_origin.setInterpolate3( ref fromB.m_origin, ref toB.m_origin, lambda ); //m_simplexSolver.reset(); //check next line supVertexA.Sub( ref supVertexB, out w ); //w = supVertexA - supVertexB; n = v; } } ///Just like regular GJK only add the vertex if it isn't already (close) to current vertex, it would lead to divisions by zero and NaN etc. if( !m_simplexSolver.inSimplex( ref w ) ) m_simplexSolver.addVertex( ref w, ref supVertexA, ref supVertexB ); if( m_simplexSolver.closest( out v ) ) { dist2 = v.length2(); //todo: check this normal for validity //n=v; //Console.WriteLine("V=%f , %f, %f\n",v,v[1],v[2]); //Console.WriteLine("DIST2=%f\n",dist2); //Console.WriteLine("numverts = %i\n",m_simplexSolver.numVertices()); } else { dist2 = btScalar.BT_ZERO; } } //int numiter = MAX_ITERATIONS - maxIter; // Console.WriteLine("number of iterations: %d", numiter); //don't report a time of impact when moving 'away' from the hitnormal result.m_fraction = lambda; if( n.length2() >= ( btScalar.SIMD_EPSILON * btScalar.SIMD_EPSILON ) ) n.normalized( out result.m_normal ); else result.m_normal = btVector3.Zero; //don't report time of impact for motion away from the contact normal (or causes minor penetration) if( result.m_normal.dot( ref r ) >= -result.m_allowedPenetration ) return false; btVector3 hitA, hitB; m_simplexSolver.compute_points( out hitA, out hitB ); result.m_hitPoint = hitB; return true; }