public Vector3 Project(Vector3 vec, float viewportX, float viewportY, float viewportWidth, float viewportHeight) { vec = vec.Project(Combined); float x = viewportWidth * (vec.X + 1) / 2 + viewportX; float y = viewportHeight * (vec.Y + 1) / 2 + viewportY; float z = (vec.Z + 1) / 2; return new Vector3(x, y, z); }
/// <summary> /// (Called by KinematicCharacterMotor during its update cycle) /// This is where you tell your character what its velocity should be right now. /// This is the ONLY place where you can set the character's velocity /// </summary> public void UpdateVelocity(ref Vector3 currentVelocity, float deltaTime) { Vector3 targetMovementVelocity = Vector3.zero; if (Motor.GroundingStatus.IsStableOnGround) { // Reorient velocity on slope currentVelocity = Motor.GetDirectionTangentToSurface(currentVelocity, Motor.GroundingStatus.GroundNormal) * currentVelocity.magnitude; // Calculate target velocity Vector3 inputRight = Vector3.Cross(_moveInputVector, Motor.CharacterUp); Vector3 reorientedInput = Vector3.Cross(Motor.GroundingStatus.GroundNormal, inputRight).normalized *_moveInputVector.magnitude; targetMovementVelocity = reorientedInput * MaxStableMoveSpeed; // Smooth movement Velocity currentVelocity = Vector3.Lerp(currentVelocity, targetMovementVelocity, 1 - Mathf.Exp(-StableMovementSharpness * deltaTime)); } else { // Add move input if (_moveInputVector.sqrMagnitude > 0f) { targetMovementVelocity = _moveInputVector * MaxAirMoveSpeed; // Prevent climbing on un-stable slopes with air movement if (Motor.GroundingStatus.FoundAnyGround) { Vector3 perpenticularObstructionNormal = Vector3.Cross(Vector3.Cross(Motor.CharacterUp, Motor.GroundingStatus.GroundNormal), Motor.CharacterUp).normalized; targetMovementVelocity = Vector3.ProjectOnPlane(targetMovementVelocity, perpenticularObstructionNormal); } Vector3 velocityDiff = Vector3.ProjectOnPlane(targetMovementVelocity - currentVelocity, Gravity); currentVelocity += velocityDiff * AirAccelerationSpeed * deltaTime; } // Gravity currentVelocity += Gravity * deltaTime; // Drag currentVelocity *= (1f / (1f + (Drag * deltaTime))); } // Handle jumping { _jumpedThisFrame = false; _timeSinceJumpRequested += deltaTime; if (_jumpRequested) { // Handle double jump if (AllowDoubleJump) { if (_jumpConsumed && !_doubleJumpConsumed && (AllowJumpingWhenSliding ? !Motor.GroundingStatus.FoundAnyGround : !Motor.GroundingStatus.IsStableOnGround)) { Motor.ForceUnground(0.1f); // Add to the return velocity and reset jump state currentVelocity += (Motor.CharacterUp * JumpSpeed) - Vector3.Project(currentVelocity, Motor.CharacterUp); _jumpRequested = false; _doubleJumpConsumed = true; _jumpedThisFrame = true; } } // See if we actually are allowed to jump if (_canWallJump || (!_jumpConsumed && ((AllowJumpingWhenSliding ? Motor.GroundingStatus.FoundAnyGround : Motor.GroundingStatus.IsStableOnGround) || _timeSinceLastAbleToJump <= JumpPostGroundingGraceTime))) { // Calculate jump direction before ungrounding Vector3 jumpDirection = Motor.CharacterUp; if (_canWallJump) { jumpDirection = _wallJumpNormal; } else if (Motor.GroundingStatus.FoundAnyGround && !Motor.GroundingStatus.IsStableOnGround) { jumpDirection = Motor.GroundingStatus.GroundNormal; } // Makes the character skip ground probing/snapping on its next update. // If this line weren't here, the character would remain snapped to the ground when trying to jump. Try commenting this line out and see. Motor.ForceUnground(0.1f); // Add to the return velocity and reset jump state currentVelocity += (jumpDirection * JumpSpeed) - Vector3.Project(currentVelocity, Motor.CharacterUp); _jumpRequested = false; _jumpConsumed = true; _jumpedThisFrame = true; } } // Reset wall jump _canWallJump = false; } }
public Vector3 GetDirection(MissileBase missile, Vector3 targetPosition, out double timeToImpact) { //set up if (_originalDistance == float.MinValue) { _startPoint = missile.vessel.CoM; _originalDistance = Vector3.Distance(targetPosition, missile.vessel.CoM); } var surfaceDistanceVector = Vector3 .Project((missile.vessel.CoM - _startPoint), (targetPosition - _startPoint).normalized); var pendingDistance = _originalDistance - surfaceDistanceVector.magnitude; timeToImpact = pendingDistance / missile.vessel.horizontalSrfSpeed; if (missile.TimeIndex < 1) { return(missile.vessel.CoM + missile.vessel.Velocity() * 10); } Vector3 agmTarget; if (missile.vessel.verticalSpeed > 0 && pendingDistance > _originalDistance * 0.5) { missile.debugString.Append($"Ascending"); missile.debugString.Append(Environment.NewLine); var freeFallTime = CalculateFreeFallTime(missile); missile.debugString.Append($"freeFallTime: {freeFallTime}"); missile.debugString.Append(Environment.NewLine); var futureDistanceVector = Vector3 .Project((missile.vessel.GetFuturePosition() - _startPoint), (targetPosition - _startPoint).normalized); var futureHorizontalSpeed = CalculateFutureHorizontalSpeed(missile); var horizontalTime = (_originalDistance - futureDistanceVector.magnitude) / futureHorizontalSpeed; missile.debugString.Append($"horizontalTime: {horizontalTime}"); missile.debugString.Append(Environment.NewLine); if (freeFallTime >= horizontalTime) { missile.debugString.Append($"Free fall achieved:"); missile.debugString.Append(Environment.NewLine); missile.Throttle = Mathf.Clamp(missile.Throttle - 0.001f, 0.01f, 1f); } else { missile.debugString.Append($"Free fall not achieved:"); missile.debugString.Append(Environment.NewLine); missile.Throttle = Mathf.Clamp(missile.Throttle + 0.001f, 0.01f, 1f); } Vector3 dToTarget = targetPosition - missile.vessel.CoM; Vector3 direction = Quaternion.AngleAxis(Mathf.Clamp(missile.maxOffBoresight * 0.9f, 0, missile.BallisticAngle), Vector3.Cross(dToTarget, VectorUtils.GetUpDirection(missile.vessel.CoM))) * dToTarget; agmTarget = missile.vessel.CoM + direction; missile.debugString.Append($"Throttle: {missile.Throttle}"); missile.debugString.Append(Environment.NewLine); } else { missile.debugString.Append($"Descending"); missile.debugString.Append(Environment.NewLine); agmTarget = MissileGuidance.GetAirToGroundTarget(targetPosition, missile.vessel, 1.85f); missile.Throttle = Mathf.Clamp((float)(missile.vessel.atmDensity * 10f), 0.01f, 1f); } if (missile is BDModularGuidance) { if (missile.vessel.InVacuum()) { missile.vessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.Prograde); agmTarget = missile.vessel.CoM + missile.vessel.Velocity() * 100; } else { missile.vessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); } } return(agmTarget); }
private Vector3 ApplyInputVelocityChange(Vector3 velocity) { if (!canControl) { inputMoveDirection = Vector3.zero; } // Find desired velocity Vector3 desiredVelocity; if (grounded && TooSteep()) { // The direction we're sliding in desiredVelocity = new Vector3(groundNormal.x, 0, groundNormal.z).normalized; // Find the input movement direction projected onto the sliding direction var projectedMoveDir = Vector3.Project(inputMoveDirection, desiredVelocity); // Add the sliding direction, the spped control, and the sideways control vectors desiredVelocity = desiredVelocity + projectedMoveDir * sliding.speedControl + (inputMoveDirection - projectedMoveDir) * sliding.sidewaysControl; // Multiply with the sliding speed desiredVelocity *= sliding.slidingSpeed; } else { desiredVelocity = GetDesiredHorizontalVelocity(); } if (movingPlatform.enabled && movingPlatform.movementTransfer == MovementTransferOnJump.PermaTransfer) { desiredVelocity += movement.frameVelocity; desiredVelocity.y = 0; } if (grounded) { desiredVelocity = AdjustGroundVelocityToNormal(desiredVelocity, groundNormal); } else { velocity.y = 0; } // Enforce max velocity change float maxVelocityChange = GetMaxAcceleration(grounded) * Time.deltaTime; Vector3 velocityChangeVector = (desiredVelocity - velocity); if (velocityChangeVector.sqrMagnitude > maxVelocityChange * maxVelocityChange) { velocityChangeVector = velocityChangeVector.normalized * maxVelocityChange; } // ifwe're in the air and don't have control, don't apply any velocity change at all. // ifwe're on the ground and don't have control we do apply it - it will correspond to friction. if (grounded || canControl) { velocity += velocityChangeVector; } if (grounded) { // When going uphill, the CharacterController will automatically move up by the needed amount. // Not moving it upwards manually prevent risk of lifting off from the ground. // When going downhill, DO move down manually, as gravity is not enough on steep hills. velocity.y = Mathf.Min(velocity.y, 0); } return(velocity); }
private Vector3 _chestRight; //right vectory of the chest // Use this for initialization void Start() { //store bones in a list for easier access, everything except Hip_Center will be one //higher than the corresponding Kinect.NuiSkeletonPositionIndex (because of the hip_override) _bones = new GameObject[(int)Kinect.NuiSkeletonPositionIndex.Count + 5] { null, Hip_Center, Spine, Shoulder_Center, Collar_Left, Shoulder_Left, Elbow_Left, Wrist_Left, Collar_Right, Shoulder_Right, Elbow_Right, Wrist_Right, Hip_Override, Hip_Left, Knee_Left, Ankle_Left, null, Hip_Right, Knee_Right, Ankle_Right, //extra joints to determine the direction of some bones Head, Hand_Left, Hand_Right, Foot_Left, Foot_Right }; //determine which bones are not available for (int ii = 0; ii < _bones.Length; ii++) { if (_bones[ii] == null) { _nullMask |= (uint)(1 << ii); } } //store the base rotations and bone directions (in bone-local space) _baseRotation = new Quaternion[(int)Kinect.NuiSkeletonPositionIndex.Count]; _boneDir = new Vector3[(int)Kinect.NuiSkeletonPositionIndex.Count]; //first save the special rotations for the hip and spine _hipRight = Hip_Right.transform.position - Hip_Left.transform.position; _hipRight = Hip_Override.transform.InverseTransformDirection(_hipRight); _chestRight = Shoulder_Right.transform.position - Shoulder_Left.transform.position; _chestRight = Spine.transform.InverseTransformDirection(_chestRight); //get direction of all other bones for (int ii = 0; ii < (int)Kinect.NuiSkeletonPositionIndex.Count; ii++) { if ((_nullMask & (uint)(1 << ii)) <= 0) { //save initial rotation _baseRotation[ii] = _bones[ii].transform.localRotation; //if the bone is the end of a limb, get direction from this bone to one of the extras (hand or foot). if (ii % 4 == 3 && ((_nullMask & (uint)(1 << (ii / 4) + (int)Kinect.NuiSkeletonPositionIndex.Count)) <= 0)) { _boneDir[ii] = _bones[(ii / 4) + (int)Kinect.NuiSkeletonPositionIndex.Count].transform.position - _bones[ii].transform.position; } //if the bone is the hip_override (at boneindex Hip_Left, get direction from average of left and right hips else if (ii == (int)Kinect.NuiSkeletonPositionIndex.HipLeft && Hip_Left != null && Hip_Right != null) { _boneDir[ii] = ((Hip_Right.transform.position + Hip_Left.transform.position) / 2F) - Hip_Override.transform.position; } //otherwise, get the vector from this bone to the next. else if ((_nullMask & (uint)(1 << ii + 1)) <= 0) { _boneDir[ii] = _bones[ii + 1].transform.position - _bones[ii].transform.position; } else { continue; } //Since the spine of the kinect data is ~40 degrees back from the hip, //check what angle the spine is at and rotate the saved direction back to match the data if (ii == (int)Kinect.NuiSkeletonPositionIndex.Spine) { float angle = Vector3.Angle(transform.up, _boneDir[ii]); _boneDir[ii] = Quaternion.AngleAxis(-40 + angle, transform.right) * _boneDir[ii]; } //transform the direction into local space. _boneDir[ii] = _bones[ii].transform.InverseTransformDirection(_boneDir[ii]); } } //make _chestRight orthogonal to the direction of the spine. _chestRight -= Vector3.Project(_chestRight, _boneDir[(int)Kinect.NuiSkeletonPositionIndex.Spine]); //make _hipRight orthogonal to the direction of the hip override Vector3.OrthoNormalize(ref _boneDir[(int)Kinect.NuiSkeletonPositionIndex.HipLeft], ref _hipRight); }
void ApplyBimanualTape(ref Vector3 pos, ref Quaternion rot) { if (m_GridSnapActive) { ApplyGridSnap(ref pos, ref rot); } if (!m_bimanualControlPointerPosition) { if (m_brushTrigger || m_RevolverActive) { m_bimanualControlPointerPosition = true; } else { m_btCursorPos = pos; m_btCursorRot = rot; return; } } Transform lAttachPoint = InputManager.m_Instance.GetWandControllerAttachPoint(); Vector3 lPos = m_GridSnapActive ? SnapToGrid(lAttachPoint.position) : lAttachPoint.position; // Quaternion lrot = lAttachPoint.rotation * sm_OrientationAdjust; Vector3 deltaPos = lPos - m_btCursorPos; Vector3 deltaBTCursor = pos - m_btCursorPos; bool reachedGoal = deltaPos.magnitude < GetSize(); Vector3 btCursorGoalDelta = Vector3.Project(deltaBTCursor, deltaPos.normalized); UpdateLazyInputRate(); // if the brush is being pulled towards the goal, then advance the brush if (!reachedGoal && Vector3.Dot(btCursorGoalDelta.normalized, deltaPos.normalized) > 0) { m_btIntersectGoal = m_btCursorPos + btCursorGoalDelta; if (m_brushTrigger) { btCursorGoalDelta = Vector3.Lerp(Vector3.zero, btCursorGoalDelta, m_lazyInputRate); if (btCursorGoalDelta.magnitude < deltaPos.magnitude) { m_btCursorPos = m_btCursorPos + btCursorGoalDelta; Transform rAttachPoint = InputManager.m_Instance.GetBrushControllerAttachPoint(); Vector3 intersectDelta = m_btIntersectGoal - (m_GridSnapActive ? SnapToGrid(rAttachPoint.position) : rAttachPoint.position); if (intersectDelta.magnitude > GetSize()) { Quaternion btCursorRotGoal = Quaternion.LookRotation(intersectDelta.normalized, deltaPos.normalized) * sm_OrientationAdjust; m_btCursorRot = Quaternion.Slerp(m_btCursorRot, btCursorRotGoal, m_lazyInputRate); } } else { m_btCursorPos = lPos; } } } pos = m_btCursorPos; rot = m_btCursorRot; }
public override void InitializeFigure() { base.InitializeFigure(); this.figType = GeoObjType.revolvedsurface; this.Position3 = centerPoint; Vector3 norm1 = Vector3.right; Vector3 norm2 = Vector3.forward; Vector3.OrthoNormalize(ref normalDirection, ref norm1, ref norm2); float radius1 = Vector3.Magnitude(Vector3.ProjectOnPlane(endpoint1 - centerPoint, normalDirection)); float radius2 = Vector3.Magnitude(Vector3.ProjectOnPlane(endpoint2 - centerPoint, normalDirection)); Vector3 ps1a = Vector3.ProjectOnPlane(endpoint1 - centerPoint, normalDirection); Vector3 ps2a = Vector3.ProjectOnPlane(endpoint2 - centerPoint, normalDirection); //Find the phase shift using the angle between the projection of radius on the plane normal to the circle, //with the sign determined by the cross product of one of the basis vecs for the plane and the projected radius. float PhaseShift1 = Mathf.Deg2Rad * (Vector3.Angle(norm1, ps1a)) * Mathf.Sign(Vector3.Dot(Vector3.Cross(norm1, ps1a), normalDirection)) + phaseshiftAdjust; //Debug.Log(PhaseShift1); float PhaseShift2 = Mathf.Deg2Rad * (Vector3.Angle(norm1, ps2a)) * Mathf.Sign(Vector3.Dot(Vector3.Cross(norm1, ps2a), normalDirection)) + phaseshiftAdjust; MeshFilter mf = GetComponent <MeshFilter>(); Mesh mesh = mf.mesh; int numvertices = 2 * n; Vector3[] vertices = new Vector3[numvertices]; int numTriangles = 6 * n; int[] triangles = new int[numTriangles]; float tauOverN = Mathf.PI * 2 / n; for (int i = 0; i < n; i++) { vertices[i] = LocalPosition(radius1 * (Mathf.Sin(PhaseShift1 + (i * tauOverN)) * norm2) + radius1 * (Mathf.Cos(PhaseShift1 + (i * tauOverN)) * norm1) + Vector3.Project(endpoint1 - centerPoint, normalDirection)); vertices[i + n] = LocalPosition(radius2 * (Mathf.Sin(PhaseShift2 + (i * tauOverN)) * norm2) + radius2 * (Mathf.Cos(PhaseShift2 + (i * tauOverN)) * norm1) + Vector3.Project(endpoint2 - centerPoint, normalDirection)); triangles[i * 6] = i; triangles[i * 6 + 1] = i + n; triangles[i * 6 + 2] = i + 1; triangles[i * 6 + 3] = i + 1; triangles[i * 6 + 4] = i + n; triangles[i * 6 + 5] = n; if (i != (n - 1)) { triangles[i * 6 + 5] = i + n + 1; } else { //i == n-1 is true triangles[i * 6 + 2] = 0; triangles[i * 6 + 3] = 0; } } mesh.vertices = vertices; mesh.triangles = triangles; mesh.RecalculateNormals(); thisSelectStatus = thisSelectStatus; }
private void SphereOnBoxCollisionAABB() { //goes through all boxes and spheres and checks the bounds to see if they collide if (Boxes.Length > 0 && Spheres.Length > 0) { foreach (GameObject Box in Boxes) { foreach (GameObject Sphere in Spheres) { //checks max and min values if (CheckForBoxCollision(Box.GetComponent <BoxColl>().Max, Box.GetComponent <BoxColl>().Min, Sphere)) { if ((Sphere.transform.position.x > Box.transform.position.x || Sphere.transform.position.x < Box.transform.position.x) && Sphere.transform.position.y > Box.GetComponent <BoxColl>().Min.y && Sphere.transform.position.y < Box.GetComponent <BoxColl>().Max.y&& Sphere.transform.position.z > Box.GetComponent <BoxColl>().Min.z && Sphere.transform.position.z < Box.GetComponent <BoxColl>().Max.z) { //checks to correct sphere on box on the x axis as i split the faces of boxes Vector3 Normalized = Vector3.Normalize(Sphere.transform.position - new Vector3(Box.transform.position.x, Sphere.transform.position.y, Sphere.transform.position.z)); float AxisXyz = Vector3.Magnitude(new Vector3(Box.transform.position.x, Sphere.transform.position.y, Sphere.transform.position.z) - Sphere.transform.position); //checking distances to see if it needs to change the transform of the object due to its penetration distance if (AxisXyz < Sphere.GetComponent <SphereColl>().Radius + Box.GetComponent <BoxColl>().Width / 2) { float PenetrationDistance = AxisXyz - (Sphere.GetComponent <SphereColl>().Radius + Box.GetComponent <BoxColl>().Width / 2); if (!Sphere.GetComponent <RigidBody>().IsGrounded) { if (!Box.GetComponent <RigidBody>().IsGrounded) { Sphere.transform.position += ((0.5f * (PenetrationDistance)) * -Normalized); Box.transform.position += ((0.5f * (PenetrationDistance)) * Normalized); } else { if (Math.Abs(Vector3.Magnitude(Sphere.GetComponent <RigidBody>().Velocity)) > 0.5f) { Sphere.transform.position += ((0.5f * (PenetrationDistance)) * -Normalized); } } } else { if (!Box.GetComponent <RigidBody>().IsGrounded) { if (Math.Abs(Vector3.Magnitude(Box.GetComponent <RigidBody>().Velocity)) > 0.5f) { Box.transform.position += (((PenetrationDistance)) * Normalized); } } } } ; //sets corrections if (Box.GetComponent <RigidBody>().UseGravity) { Vector3 NewVelocity1; Vector3 NewVelocity2; NewVelocity1 = Box.GetComponent <RigidBody>().Velocity; NewVelocity1 += Vector3.Project(Sphere.GetComponent <RigidBody>().Velocity, Sphere.transform.position - Box.transform.position); NewVelocity1 -= Vector3.Project(Box.GetComponent <RigidBody>().Velocity, Box.transform.position - Sphere.transform.position); NewVelocity2 = Sphere.GetComponent <RigidBody>().Velocity; NewVelocity2 += Vector3.Project(Box.GetComponent <RigidBody>().Velocity, Sphere.transform.position - Box.transform.position); NewVelocity2 -= Vector3.Project(Sphere.GetComponent <RigidBody>().Velocity, Box.transform.position - Sphere.transform.position); Sphere.GetComponent <RigidBody>().Velocity = new Vector3(NewVelocity2.x, Sphere.GetComponent <RigidBody>().Velocity.y, NewVelocity2.z); Box.GetComponent <RigidBody>().Velocity = new Vector3(NewVelocity1.x, Box.GetComponent <RigidBody>().Velocity.y, NewVelocity1.z); } else { Vector3 Velocity; Vector3 reflectedVelocity; Velocity = Sphere.GetComponent <RigidBody>().Velocity; reflectedVelocity.x = Sphere.GetComponent <RigidBody>().Velocity.x - (Sphere.GetComponent <RigidBody>().Bounce *(Velocity.x)); Sphere.GetComponent <RigidBody>().Velocity.x = reflectedVelocity.x; } //simulates the reaction on the x axis } else if ((Sphere.transform.position.y > Box.transform.position.y || Sphere.transform.position.y < Box.transform.position.y) && Sphere.transform.position.x > Box.GetComponent <BoxColl>().Min.x && Sphere.transform.position.x < Box.GetComponent <BoxColl>().Max.x&& Sphere.transform.position.z > Box.GetComponent <BoxColl>().Min.z && Sphere.transform.position.z < Box.GetComponent <BoxColl>().Max.z) { //checks to correct sphere on box on the y axis as i split the faces of boxes Vector3 Normalized = Vector3.Normalize(Sphere.transform.position - new Vector3(Sphere.transform.position.x, Box.transform.position.y, Sphere.transform.position.z)); float AxisXyz = Vector3.Magnitude(new Vector3(Sphere.transform.position.x, Box.transform.position.y, Sphere.transform.position.z) - Sphere.transform.position); //checking distances to see if it needs to change the transform of the object due to its penetration distance if (AxisXyz < Sphere.GetComponent <SphereColl>().Radius + Box.GetComponent <BoxColl>().Height / 2) { float PenetrationDistance = AxisXyz - (Sphere.GetComponent <SphereColl>().Radius + Box.GetComponent <BoxColl>().Height / 2); if (!Sphere.GetComponent <RigidBody>().IsGrounded) { if (!Box.GetComponent <RigidBody>().IsGrounded) { Sphere.transform.position += ((0.5f * (PenetrationDistance)) * -Normalized); Box.transform.position += ((0.5f * (PenetrationDistance)) * Normalized); } else { if (Math.Abs(Vector3.Magnitude(Sphere.GetComponent <RigidBody>().Velocity)) > 0.5f) { Sphere.transform.position += ((0.5f * (PenetrationDistance)) * -Normalized); } } } else { if (!Box.GetComponent <RigidBody>().IsGrounded) { if (Math.Abs(Vector3.Magnitude(Box.GetComponent <RigidBody>().Velocity)) > 0.5f) { Box.transform.position += (((PenetrationDistance)) * Normalized); } } } } //sets corrections Vector3 Velocity; Vector3 reflectedVelocity; //checks last collided Sphere.GetComponent <SphereColl>().LastCollided = Box; //sets velocity Velocity = Sphere.GetComponent <RigidBody>().Velocity; //sets reflected velocity reflectedVelocity.y = Sphere.GetComponent <RigidBody>().Velocity.y - (Sphere.GetComponent <RigidBody>().Bounce *(Velocity.y)); Sphere.GetComponent <RigidBody>().Velocity.y = reflectedVelocity.y; //if the sphere is higher than the box if (Sphere.transform.position.y > Box.transform.position.y) { //apply force Sphere.GetComponent <RigidBody>().Force -= Sphere.GetComponent <RigidBody>().Gravity; Sphere.GetComponent <RigidBody>().IsGrounded = true; } //simulates on the y axis } else if ((Sphere.transform.position.z > Box.transform.position.z || Sphere.transform.position.z < Box.transform.position.z) && Sphere.transform.position.x > Box.GetComponent <BoxColl>().Min.x && Sphere.transform.position.x < Box.GetComponent <BoxColl>().Max.x&& Sphere.transform.position.y > Box.GetComponent <BoxColl>().Min.y && Sphere.transform.position.y < Box.GetComponent <BoxColl>().Max.y) { //checks to correct sphere on box on the z axis as i split the faces of boxes Vector3 Normalized = Vector3.Normalize(Sphere.transform.position - new Vector3(Sphere.transform.position.x, Sphere.transform.position.y, Box.transform.position.z)); float AxisXyz = Vector3.Magnitude(new Vector3(Sphere.transform.position.x, Sphere.transform.position.y, Box.transform.position.z) - Sphere.transform.position); //checking distances to see if it needs to change the transform of the object due to its penetration distance if (AxisXyz < Sphere.GetComponent <SphereColl>().Radius + Box.GetComponent <BoxColl>().Depth / 2) { float PenetrationDistance = AxisXyz - (Sphere.GetComponent <SphereColl>().Radius + Box.GetComponent <BoxColl>().Depth / 2); if (!Sphere.GetComponent <RigidBody>().IsGrounded) { if (!Box.GetComponent <RigidBody>().IsGrounded) { Sphere.transform.position += ((0.5f * (PenetrationDistance)) * -Normalized); Box.transform.position += ((0.5f * (PenetrationDistance)) * Normalized); } else { if (Math.Abs(Sphere.GetComponent <RigidBody>().Velocity.z) > 0.5f) { Sphere.transform.position += ((0.5f * (PenetrationDistance)) * -Normalized); } } } else { if (!Box.GetComponent <RigidBody>().IsGrounded) { if (Math.Abs(Vector3.Magnitude(Box.GetComponent <RigidBody>().Velocity)) > 0.5f) { Box.transform.position += ((0.5f * (PenetrationDistance)) * Normalized); } } } } //sets corrections if (Box.GetComponent <RigidBody>().UseGravity) { Vector3 NewVelocity1; Vector3 NewVelocity2; NewVelocity1 = Box.GetComponent <RigidBody>().Velocity; NewVelocity1 += Vector3.Project(Sphere.GetComponent <RigidBody>().Velocity, Sphere.transform.position - Box.transform.position); NewVelocity1 -= Vector3.Project(Box.GetComponent <RigidBody>().Velocity, Box.transform.position - Sphere.transform.position); NewVelocity2 = Sphere.GetComponent <RigidBody>().Velocity; NewVelocity2 += Vector3.Project(Box.GetComponent <RigidBody>().Velocity, Sphere.transform.position - Box.transform.position); NewVelocity2 -= Vector3.Project(Sphere.GetComponent <RigidBody>().Velocity, Box.transform.position - Sphere.transform.position); Sphere.GetComponent <RigidBody>().Velocity = new Vector3(NewVelocity2.x, Sphere.GetComponent <RigidBody>().Velocity.y, NewVelocity2.z); Box.GetComponent <RigidBody>().Velocity = new Vector3(NewVelocity1.x, Box.GetComponent <RigidBody>().Velocity.y, NewVelocity1.z); } else { Vector3 Velocity; Vector3 reflectedVelocity; Velocity = Sphere.GetComponent <RigidBody>().Velocity; reflectedVelocity.z = Sphere.GetComponent <RigidBody>().Velocity.z - (Sphere.GetComponent <RigidBody>().Bounce *(Velocity.z)); Sphere.GetComponent <RigidBody>().Velocity.z = reflectedVelocity.z; } } } } } } }
private void CollisionWithBoxResponse(GameObject Box1, GameObject Box2) { Vector3 PenetrationDistance; Vector3 AbsPenetrationDistance; //sets box penetration distance float AxisXyz = Vector3.Magnitude(new Vector3(Box1.transform.position.x, Box2.transform.position.y, Box2.transform.position.z) - Box2.transform.position); if (AxisXyz < Box1.GetComponent <BoxColl>().Width / 2 + Box2.GetComponent <BoxColl>().Width / 2) { PenetrationDistance.x = AxisXyz - (Box2.GetComponent <BoxColl>().Width / 2 + Box1.GetComponent <BoxColl>().Width / 2); } else { PenetrationDistance.x = 300f; } AxisXyz = Vector3.Magnitude(new Vector3(Box2.transform.position.x, Box1.transform.position.y, Box2.transform.position.z) - Box2.transform.position); if (AxisXyz < Box2.GetComponent <BoxColl>().Height / 2 + Box1.GetComponent <BoxColl>().Height / 2) { PenetrationDistance.y = AxisXyz - (Box2.GetComponent <BoxColl>().Height / 2 + Box1.GetComponent <BoxColl>().Height / 2); } else { PenetrationDistance.y = 300f; } AxisXyz = Vector3.Magnitude(new Vector3(Box2.transform.position.x, Box2.transform.position.y, Box1.transform.position.z) - Box2.transform.position); if (AxisXyz < Box2.GetComponent <BoxColl>().Depth / 2 + Box1.GetComponent <BoxColl>().Depth / 2) { PenetrationDistance.z = AxisXyz - (Box2.GetComponent <BoxColl>().Depth / 2 + Box1.GetComponent <BoxColl>().Depth / 2); } else { PenetrationDistance.z = 300f; } AbsPenetrationDistance.x = Math.Abs(PenetrationDistance.x); AbsPenetrationDistance.y = Math.Abs(PenetrationDistance.y); AbsPenetrationDistance.z = Math.Abs(PenetrationDistance.z); //checks the abs of the penetration distance //these if statements check the face it impacted with. if (AbsPenetrationDistance.x < AbsPenetrationDistance.y) { if (AbsPenetrationDistance.x < AbsPenetrationDistance.z) { GenerateCorrection(Box1, Box2, PenetrationDistance.x); if (Box1.GetComponent <RigidBody>().UseGravity) { if (Box2.GetComponent <RigidBody>().UseGravity) { if (Box1.GetComponent <RigidBody>().UseGravity) { Vector3 NewVelocity1; Vector3 NewVelocity2; NewVelocity1 = Box1.GetComponent <RigidBody>().Velocity; NewVelocity1 += Vector3.Project(Box2.GetComponent <RigidBody>().Velocity, Box2.transform.position - Box1.transform.position); NewVelocity1 -= Vector3.Project(Box1.GetComponent <RigidBody>().Velocity, Box1.transform.position - Box2.transform.position); NewVelocity2 = Box2.GetComponent <RigidBody>().Velocity; NewVelocity2 += Vector3.Project(Box1.GetComponent <RigidBody>().Velocity, Box2.transform.position - Box1.transform.position); NewVelocity2 -= Vector3.Project(Box2.GetComponent <RigidBody>().Velocity, Box1.transform.position - Box2.transform.position); Box2.GetComponent <RigidBody>().Velocity = new Vector3(NewVelocity2.x, Box2.GetComponent <RigidBody>().Velocity.y, NewVelocity2.z); Box1.GetComponent <RigidBody>().Velocity = new Vector3(NewVelocity1.x, Box1.GetComponent <RigidBody>().Velocity.y, NewVelocity1.z); } else { Vector3 Velocity; Vector3 reflectedVelocity; Velocity = Box2.GetComponent <RigidBody>().Velocity; reflectedVelocity.x = Box2.GetComponent <RigidBody>().Velocity.x - (Box2.GetComponent <RigidBody>().Bounce *(Velocity.x)); Box2.GetComponent <RigidBody>().Velocity.x = reflectedVelocity.x; } } else { Vector3 Velocity; Vector3 reflectedVelocity; Velocity = Box1.GetComponent <RigidBody>().Velocity; reflectedVelocity.x = Box1.GetComponent <RigidBody>().Velocity.x - (Box1.GetComponent <RigidBody>().Bounce *(Velocity.x)); Box1.GetComponent <RigidBody>().Velocity.x = reflectedVelocity.x; } } else { if (Box2.GetComponent <RigidBody>().UseGravity) { Vector3 Velocity; Vector3 reflectedVelocity; Velocity = Box2.GetComponent <RigidBody>().Velocity; reflectedVelocity.x = Box2.GetComponent <RigidBody>().Velocity.x - (Box2.GetComponent <RigidBody>().Bounce *(Velocity.x)); Box2.GetComponent <RigidBody>().Velocity.x = reflectedVelocity.x; } } } else { GenerateCorrection(Box1, Box2, PenetrationDistance.z); if (Box1.GetComponent <RigidBody>().UseGravity) { if (Box2.GetComponent <RigidBody>().UseGravity) { if (Box1.GetComponent <RigidBody>().UseGravity) { Vector3 NewVelocity1; Vector3 NewVelocity2; NewVelocity1 = Box1.GetComponent <RigidBody>().Velocity; NewVelocity1 += Vector3.Project(Box2.GetComponent <RigidBody>().Velocity, Box2.transform.position - Box1.transform.position); NewVelocity1 -= Vector3.Project(Box1.GetComponent <RigidBody>().Velocity, Box1.transform.position - Box2.transform.position); NewVelocity2 = Box2.GetComponent <RigidBody>().Velocity; NewVelocity2 += Vector3.Project(Box1.GetComponent <RigidBody>().Velocity, Box2.transform.position - Box1.transform.position); NewVelocity2 -= Vector3.Project(Box2.GetComponent <RigidBody>().Velocity, Box1.transform.position - Box2.transform.position); Box2.GetComponent <RigidBody>().Velocity = new Vector3(NewVelocity2.x, Box2.GetComponent <RigidBody>().Velocity.y, NewVelocity2.z); Box1.GetComponent <RigidBody>().Velocity = new Vector3(NewVelocity1.x, Box1.GetComponent <RigidBody>().Velocity.y, NewVelocity1.z); } else { Vector3 Velocity; Vector3 reflectedVelocity; Velocity = Box2.GetComponent <RigidBody>().Velocity; reflectedVelocity.z = Box2.GetComponent <RigidBody>().Velocity.z - (Box2.GetComponent <RigidBody>().Bounce *(Velocity.z)); Box2.GetComponent <RigidBody>().Velocity.z = reflectedVelocity.z; } } else { Vector3 Velocity; Vector3 reflectedVelocity; Velocity = Box1.GetComponent <RigidBody>().Velocity; reflectedVelocity.z = Box1.GetComponent <RigidBody>().Velocity.z - (Box1.GetComponent <RigidBody>().Bounce *(Velocity.z)); Box1.GetComponent <RigidBody>().Velocity.z = reflectedVelocity.z; } } else { if (Box2.GetComponent <RigidBody>().UseGravity) { Vector3 Velocity; Vector3 reflectedVelocity; Velocity = Box2.GetComponent <RigidBody>().Velocity; reflectedVelocity.z = Box2.GetComponent <RigidBody>().Velocity.z - (Box2.GetComponent <RigidBody>().Bounce *(Velocity.z)); Box2.GetComponent <RigidBody>().Velocity.z = reflectedVelocity.z; } } } } else { if (AbsPenetrationDistance.y < AbsPenetrationDistance.z) { GenerateCorrection(Box1, Box2, PenetrationDistance.y); Vector3 Velocity; Vector3 reflectedVelocity; Velocity = Box1.GetComponent <RigidBody>().Velocity; reflectedVelocity.y = Box1.GetComponent <RigidBody>().Velocity.y - (Box1.GetComponent <RigidBody>().Bounce *(Velocity.y)); Box1.GetComponent <RigidBody>().Velocity.y = reflectedVelocity.y; if (Box1.transform.position.y > Box2.transform.position.y && Box2.GetComponent <RigidBody>().IsGrounded) { Box1.GetComponent <RigidBody>().Force -= Box1.GetComponent <RigidBody>().Gravity; } Velocity = Box2.GetComponent <RigidBody>().Velocity; reflectedVelocity.y = Box2.GetComponent <RigidBody>().Velocity.y - (Box2.GetComponent <RigidBody>().Bounce *(Velocity.y)); Box2.GetComponent <RigidBody>().Velocity.y = reflectedVelocity.y; if (Box2.transform.position.y > Box1.transform.position.y && Box1.GetComponent <RigidBody>().IsGrounded) { Box2.GetComponent <RigidBody>().Force -= Box2.GetComponent <RigidBody>().Gravity; } } else if (AbsPenetrationDistance.y > AbsPenetrationDistance.z) { GenerateCorrection(Box1, Box2, PenetrationDistance.z); if (Box1.GetComponent <RigidBody>().UseGravity) { if (Box2.GetComponent <RigidBody>().UseGravity) { if (Box1.GetComponent <RigidBody>().UseGravity) { Vector3 NewVelocity1; Vector3 NewVelocity2; NewVelocity1 = Box1.GetComponent <RigidBody>().Velocity; NewVelocity1 += Vector3.Project(Box2.GetComponent <RigidBody>().Velocity, Box2.transform.position - Box1.transform.position); NewVelocity1 -= Vector3.Project(Box1.GetComponent <RigidBody>().Velocity, Box1.transform.position - Box2.transform.position); NewVelocity2 = Box2.GetComponent <RigidBody>().Velocity; NewVelocity2 += Vector3.Project(Box1.GetComponent <RigidBody>().Velocity, Box2.transform.position - Box1.transform.position); NewVelocity2 -= Vector3.Project(Box2.GetComponent <RigidBody>().Velocity, Box1.transform.position - Box2.transform.position); Box2.GetComponent <RigidBody>().Velocity = new Vector3(NewVelocity2.x, Box2.GetComponent <RigidBody>().Velocity.y, NewVelocity2.z); Box1.GetComponent <RigidBody>().Velocity = new Vector3(NewVelocity1.x, Box1.GetComponent <RigidBody>().Velocity.y, NewVelocity1.z); } else { Vector3 Velocity; Vector3 reflectedVelocity; Velocity = Box2.GetComponent <RigidBody>().Velocity; reflectedVelocity.z = Box2.GetComponent <RigidBody>().Velocity.z - (Box2.GetComponent <RigidBody>().Bounce *(Velocity.z)); Box2.GetComponent <RigidBody>().Velocity.z = reflectedVelocity.z; } } else { Vector3 Velocity; Vector3 reflectedVelocity; Velocity = Box2.GetComponent <RigidBody>().Velocity; reflectedVelocity.z = Box2.GetComponent <RigidBody>().Velocity.z - (Box2.GetComponent <RigidBody>().Bounce *(Velocity.z)); Box2.GetComponent <RigidBody>().Velocity.z = reflectedVelocity.z; } } else { if (Box2.GetComponent <RigidBody>().UseGravity) { Vector3 Velocity; Vector3 reflectedVelocity; Velocity = Box2.GetComponent <RigidBody>().Velocity; reflectedVelocity.z = Box2.GetComponent <RigidBody>().Velocity.z - (Box2.GetComponent <RigidBody>().Bounce *(Velocity.z)); Box2.GetComponent <RigidBody>().Velocity.z = reflectedVelocity.z; } } } } }
public static Vector3 getRayPoint(Ray ray, Vector3 point) { return(ray.origin + Vector3.Project(point - ray.origin, ray.direction)); }
void UpdateClimbing() { Vector3 projectPos = Vector3.zero; for (; m_CurrentMoveIndex < mLinePosList.Count - 1; ++m_CurrentMoveIndex) { Vector3 indexDir = mLinePosList[m_CurrentMoveIndex + 1] - mLinePosList[m_CurrentMoveIndex]; Vector3 currentDir = mRopeGun.gunMuzzle.position - mLinePosList[m_CurrentMoveIndex]; Vector3 projectDir = Vector3.Project(currentDir, indexDir); if (projectDir.sqrMagnitude < PETools.PEMath.Epsilon || Vector3.Angle(projectDir, indexDir) > 90f || projectDir.sqrMagnitude < indexDir.sqrMagnitude) { projectPos = mLinePosList[m_CurrentMoveIndex] + projectDir; break; } } if (phyCtrl.velocity.magnitude > 5f * mRopeGun.climbSpeed || Vector3.SqrMagnitude(trans.position - m_LastHookPos) > 40000f) { trans.position = m_LastHookPos + 2f * Vector3.up; mState = HookGunState.Null; ResetPhy(); return; } if (m_CurrentMoveIndex == mLinePosList.Count - 1 || Vector3.SqrMagnitude(projectPos - m_LastHookPos) <= 0.25f || (Time.time >= m_ExDoClimbTime && phyCtrl.grounded)) { mState = HookGunState.Null; ResetPhy(); return; } mRopeGun.hook.position = m_LastHookPos; Vector3 targetToProjectPos = projectPos - m_LastHookPos; Vector3 targetToHookPos = mRopeGun.gunMuzzle.position - m_LastHookPos; float angle = Vector3.Angle(targetToHookPos, targetToProjectPos); if (angle > PETools.PEMath.Epsilon) { Vector3 normal = Vector3.Cross(targetToProjectPos.normalized, targetToHookPos.normalized); Quaternion rot = Quaternion.AngleAxis(angle, normal); for (int i = m_CurrentMoveIndex; i < mLinePosList.Count - 1; ++i) { Vector3 dir = mLinePosList[i] - m_LastHookPos; dir = rot * dir; mLinePosList[i] = dir + m_LastHookPos; } } Vector3 moveDir = Vector3.Normalize(mLinePosList[m_CurrentMoveIndex + 1] - mLinePosList[m_CurrentMoveIndex]); phyCtrl.m_SubAcc = moveDir.y > 0 ? Physics.gravity.y * Vector3.down : Vector3.zero; phyCtrl.ResetSpeed(((moveDir.y > 0)?1f:mRopeGun.moveDownSpeedScale) * mRopeGun.climbSpeed); phyCtrl.desiredMovementDirection = moveDir; for (int i = 0; i < mRopeGun.lineList.Count; i++) { if (i < m_CurrentMoveIndex + 1) { mRopeGun.lineList[i].localPosition = Vector3.zero; } else { mRopeGun.lineList[i].position = mLinePosList[i]; } } }
public static Vector3 getPerpendicularVectorVector(Vector3 current, Vector3 normal) { return(current - Vector3.Project(current, normal)); }
// Update is called once per frame void Update() { transform.LookAt(new Vector3(currentAim.position.x, transform.position.y, currentAim.position.z)); //rb.AddForce(transform.forward * Time.deltaTime, ForceMode.VelocityChange); rb.velocity = transform.forward * Time.deltaTime * moveForce + Vector3.Project(rb.velocity, Vector3.up); }
internal void findBoundPoints() { Vector3 lowestPoint = Vector3.zero; Vector3 highestPoint = Vector3.zero; Part downwardFurthestPart = vessel.rootPart; Part upwardFurthestPart = vessel.rootPart; up = (vessel.CoM - vessel.mainBody.transform.position).normalized; Vector3 downPoint = vessel.CoM - (2000 * up); Vector3 upPoint = vessel.CoM + (2000 * up); Vector3 closestVert = vessel.CoM; Vector3 farthestVert = vessel.CoM; float closestSqrDist = Mathf.Infinity; float farthestSqrDist = Mathf.Infinity; foreach (Part p in vessel.parts) { if (p.Modules.Contains("KASModuleHarpoon")) { continue; } HashSet <Pair <Transform, Mesh> > meshes = new HashSet <Pair <Transform, Mesh> >(); foreach (MeshFilter filter in p.GetComponentsInChildren <MeshFilter>()) { Collider[] cdr = filter.GetComponentsInChildren <Collider>(); if (cdr.Length > 0 || p.Modules.Contains("ModuleWheelSuspension")) { // for whatever reason suspension needs an additional treatment // TODO: Maybe address it by searching for wheel collider meshes.Add(new Pair <Transform, Mesh>(filter.transform, filter.mesh)); } } foreach (MeshCollider mcdr in p.GetComponentsInChildren <MeshCollider>()) { meshes.Add(new Pair <Transform, Mesh>(mcdr.transform, mcdr.sharedMesh)); } foreach (Pair <Transform, Mesh> meshpair in meshes) { Mesh mesh = meshpair.Second; Transform tr = meshpair.First; foreach (Vector3 vert in mesh.vertices) { //bottom check Vector3 worldVertPoint = tr.TransformPoint(vert); float bSqrDist = (downPoint - worldVertPoint).sqrMagnitude; if (bSqrDist < closestSqrDist) { closestSqrDist = bSqrDist; closestVert = worldVertPoint; downwardFurthestPart = p; // TODO: Not used at the moment, but we might infer amount of // TODO: upward movement from this // If this is a landing gear, account for suspension compression /*if (p.Modules.Contains ("ModuleWheelSuspension")) { * ModuleWheelSuspension suspension = p.GetComponent<ModuleWheelSuspension> (); * if (maxSuspensionTravel < suspension.suspensionDistance) * maxSuspensionTravel = suspension.suspensionDistance; * printDebug ("Suspension: dist=" + suspension.suspensionDistance + "; offset=" + suspension.suspensionOffset + "; pos=(" + suspension.suspensionPos.x + "; " + suspension.suspensionPos.y + "; " + suspension.suspensionPos.z + ")"); + }*/ } bSqrDist = (upPoint - worldVertPoint).sqrMagnitude; if (bSqrDist < farthestSqrDist) { farthestSqrDist = bSqrDist; farthestVert = worldVertPoint; upwardFurthestPart = p; } } } } bottomLength = Vector3.Project(closestVert - vessel.CoM, up).magnitude; localBottomPoint = vessel.transform.InverseTransformPoint(closestVert); topLength = Vector3.Project(farthestVert - vessel.CoM, up).magnitude; localTopPoint = vessel.transform.InverseTransformPoint(farthestVert); bottomPart = downwardFurthestPart; }
public static bool DodgeWall(Transform cameraP, Vector3 alvo, float escalA, bool suave = false, bool changeRotation = true) { RaycastHit raioColisor; if (antPos == default) { antPos = cameraP.position; } Vector3 posAlvo = alvo + escalA * Vector3.up; Vector3 proj = Vector3.Project(posAlvo - cameraP.position, Vector3.up); Debug.DrawLine(cameraP.position, posAlvo, Color.blue); Debug.DrawLine(posAlvo, cameraP.position + proj, Color.green); tempoAvancando += Time.deltaTime; if (Physics.Linecast(posAlvo, cameraP.position, out raioColisor, 9)) { Debug.DrawLine(cameraP.position, raioColisor.point, Color.red); if (suave) { if (VerifyTags(raioColisor)) { VerifiqueAcionamento(cameraP.position, true); cameraP.position = Vector3.Lerp(startPos, raioColisor.point + raioColisor.normal * 0.2f, tempoAvancando / totalTimeIn); if (changeRotation) { cameraP.rotation = Quaternion.LookRotation(-cameraP.position + posAlvo); } antPos = cameraP.position; return(true); } else { VerifiqueAcionamento(cameraP.position, false); cameraP.position = Vector3.Lerp(startPos, cameraP.position, tempoAvancando / totalTimeOut); if (changeRotation) { cameraP.rotation = Quaternion.LookRotation(-cameraP.position + posAlvo); } } } else if (VerifyTags(raioColisor)) { cameraP.position = //Vector3.Lerp(cameraP.position, raioColisor.point + cameraP.forward * 0.2f; return(true); } } else if (suave) { VerifiqueAcionamento(antPos, false); cameraP.position = Vector3.Lerp(startPos, cameraP.position, tempoAvancando / totalTimeOut); if (changeRotation) { cameraP.rotation = Quaternion.LookRotation(-cameraP.position + posAlvo); } } return(false); }
/// <summary> /// Gets the angle of rotation between two directions around the specified axis. /// </summary> /// <param name="directionA">The first direction.</param> /// <param name="directionB">The second direction.</param> /// <param name="axis">The axis of rotation.</param> /// <returns> /// The rotation angle. /// </returns> public static float AngleAroundAxis(this Vector3 directionA, Vector3 directionB, Vector3 axis) { directionA -= Vector3.Project(directionA, axis); directionB -= Vector3.Project(directionB, axis); return(Vector3.Angle(directionA, directionB) * (Vector3.Dot(axis, Vector3.Cross(directionA, directionB)) < 0 ? -1 : 1)); }
//--------------------------------------------------------------------------------------------------- /// <summary> /// Method that updates the Snap status on each face when it is Active. It updates the exactSnap staus for both /// corner and face, and also the snapZone status for corner and face. /// </summary> /// <param name="snapDist">Snap distance used for face snap.</param> /// <param name="cornerSnap">Snap distance used for corner snap.</param> /// <returns></returns> private bool ActivateSnapZone(float snapDist, float cornerSnap) { List <GameObject> list = BLOCK_COMP.PROXI_COLLIDER.closeBlocksColl; Vector3 moveVec2 = new Vector3(); if (list.Count > 0) { // Find shortest vector. float minDist = 1000; float cornerSnapDist = 1000; //Vector3 closestEdge = new Vector3(); //Vector3 closestEdgeProxi = new Vector3(); for (int i = 0; i < list.Count; i++) { List <object> snapList = Snap(i); Vector3 closeVec = (Vector3)snapList[1]; if (closeVec.magnitude < minDist) { minDist = closeVec.magnitude; moveVec2 = closeVec; } //-------------------------------------------------------------------------- // Find the closest edge of this obj and the coresponded closest edge of proxi obj that fits // the snapDist comparison. (This part is used in the Corner Snap only.) for (int j = 0; j < FACE_EDGE_MID_COLL.Length; j++) { Vector3 edgeMidThis = FACE_EDGE_MID_COLL[j]; //list[i].GetComponent<BlockPrim>().EDGE_MID_COLL.Length for (int h = 0; h < 4; h++) { Vector3 edgeMidProxi = list[i].GetComponent <BlockPrim>().EDGE_MID_COLL[h]; if ((edgeMidThis - edgeMidProxi).magnitude < cornerSnapDist) { cornerSnapDist = (edgeMidThis - edgeMidProxi).magnitude; //closestEdge = edgeMidThis; //closestEdgeProxi = list[i].GetComponent<BlockPrim>().EDGE_MID_COLL[h]; } } } } //-------------------------------------------------------------------------- // 1. Corner snap has the most priority. if (cornerSnapDist < cornerSnap) { _cornerSnapZone = true; _faceSnapZone = false; if (cornerSnapDist < 0.0001f) { _exactCornerSnap = true; _exactFaceSnap = false; } //if (BLOCK_COMP.name == "Block" && this.name == "face_pos_z") print("Zero [" + "]: " + cornerSnapDist); return(true); } // 2. Apply face snap from this as priority. else if (Vector3.Project(moveVec2, FACE_NORMAL_WORLD).magnitude < snapDist) { _cornerSnapZone = false; _faceSnapZone = true; if (Vector3.Project(moveVec2, FACE_NORMAL_WORLD).magnitude < 0.0001f) { _exactCornerSnap = false; _exactFaceSnap = true; } //if (BLOCK_COMP.name == "Block" && this.name == "face_pos_z") print("First [" + "]: " + minDist); return(true); } else { // Influence Snap Zone _cornerSnapZone = false; _faceSnapZone = false; // Exact snaps. _exactCornerSnap = false; _exactFaceSnap = false; //print("No snap -2- !"); return(false); } } else { // Influence Snap Zone _cornerSnapZone = false; _faceSnapZone = false; // Exact snaps. _exactCornerSnap = false; _exactFaceSnap = false; //print("No snap!"); return(false); } }
//Where the damage is actually applied void DamageApplication(Vector3 damagePoint, Vector3 damageForce, float damageForceLimit, Vector3 surfaceNormal, ContactPoint colPoint, bool useContactPoint) { var colMag = Mathf.Min(damageForce.magnitude, this.maxCollisionMagnitude) * (1 - this.strength) * this.damageFactor; //Magnitude of collision var clampedColMag = Mathf.Pow(Mathf.Sqrt(colMag) * 0.5f, 1.5f); //Clamped magnitude of collision var clampedVel = Vector3.ClampMagnitude(damageForce, damageForceLimit); //Clamped velocity of collision var normalizedVel = damageForce.normalized; float surfaceDot; //Dot production of collision velocity and surface normal float massFactor = 1; //Multiplier for damage based on mass of other rigidbody Transform curDamagePart; float damagePartFactor; MeshFilter curDamageMesh; Transform curDisplacePart; Transform seamKeeper = null; //Transform for maintaining seams on shattered parts Vector3 seamLocalPoint; Vector3 vertProjection; Vector3 translation; Vector3 clampedTranslation; Vector3 localPos; float vertDist; float distClamp; DetachablePart detachedPart; Suspension.Suspension damagedSus; //Get mass factor for multiplying damage if (useContactPoint) { damagePoint = colPoint.point; surfaceNormal = colPoint.normal; if (colPoint.otherCollider.attachedRigidbody) { massFactor = Mathf.Clamp01(colPoint.otherCollider.attachedRigidbody.mass / this.rb.mass); } } surfaceDot = Mathf.Clamp01(Vector3.Dot(surfaceNormal, normalizedVel)) * (Vector3.Dot((this.tr.position - damagePoint).normalized, normalizedVel) + 1) * 0.5f; //Damage damageable parts for (var i = 0; i < this.damageParts.Length; i++) { curDamagePart = this.damageParts[i]; damagePartFactor = colMag * surfaceDot * massFactor * Mathf.Min(clampedColMag * 0.01f, (clampedColMag * 0.001f) / Mathf.Pow(Vector3.Distance(curDamagePart.position, damagePoint), clampedColMag)); //Damage motors var damagedMotor = curDamagePart.GetComponent <Motor>(); if (damagedMotor) { damagedMotor.health -= damagePartFactor * (1 - damagedMotor.strength); } //Damage transmissions var damagedTransmission = curDamagePart.GetComponent <Transmission>(); if (damagedTransmission) { damagedTransmission.health -= damagePartFactor * (1 - damagedTransmission.strength); } } //Deform meshes for (var i = 0; i < this.deformMeshes.Length; i++) { curDamageMesh = this.deformMeshes[i]; localPos = curDamageMesh.transform.InverseTransformPoint(damagePoint); translation = curDamageMesh.transform.InverseTransformDirection(clampedVel); clampedTranslation = Vector3.ClampMagnitude(translation, clampedColMag); //Shatter parts that can shatter var shattered = curDamageMesh.GetComponent <ShatterPart>(); if (shattered) { seamKeeper = shattered.seamKeeper; if (Vector3.Distance(curDamageMesh.transform.position, damagePoint) < colMag * surfaceDot * 0.1f * massFactor && colMag * surfaceDot * massFactor > shattered.breakForce) { shattered.Shatter(); } } //Actual deformation if (translation.sqrMagnitude > 0 && this.strength < 1) { for (var j = 0; j < this.meshVertices[i].verts.Length; j++) { vertDist = Vector3.Distance(this.meshVertices[i].verts[j], localPos); distClamp = (clampedColMag * 0.001f) / Mathf.Pow(vertDist, clampedColMag); if (distClamp > 0.001f) { this.damagedMeshes[i] = true; if (seamKeeper == null || this.seamlessDeform) { vertProjection = this.seamlessDeform ? Vector3.zero : Vector3.Project(normalizedVel, this.meshVertices[i].verts[j]); this.meshVertices[i].verts[j] += (clampedTranslation - vertProjection * (this.usePerlinNoise ? 1 + Mathf.PerlinNoise(this.meshVertices[i].verts[j].x * 100, this.meshVertices[i].verts[j].y * 100) : 1)) * surfaceDot * Mathf.Min(clampedColMag * 0.01f, distClamp) * massFactor; } else { seamLocalPoint = seamKeeper.InverseTransformPoint(curDamageMesh .transform .TransformPoint(this.meshVertices[i].verts[j])); this.meshVertices[i].verts[j] += (clampedTranslation - Vector3.Project(normalizedVel, seamLocalPoint) * (this.usePerlinNoise ? 1 + Mathf.PerlinNoise(seamLocalPoint.x * 100, seamLocalPoint.y * 100) : 1)) * surfaceDot * Mathf.Min(clampedColMag * 0.01f, distClamp) * massFactor; } } } } } seamKeeper = null; //Deform mesh colliders for (var i = 0; i < this.deformColliders.Length; i++) { localPos = this.deformColliders[i].transform.InverseTransformPoint(damagePoint); translation = this.deformColliders[i].transform.InverseTransformDirection(clampedVel); clampedTranslation = Vector3.ClampMagnitude(translation, clampedColMag); if (translation.sqrMagnitude > 0 && this.strength < 1) { for (var j = 0; j < this.colVertices[i].verts.Length; j++) { vertDist = Vector3.Distance(this.colVertices[i].verts[j], localPos); distClamp = (clampedColMag * 0.001f) / Mathf.Pow(vertDist, clampedColMag); if (distClamp > 0.001f) { this.damagedCols[i] = true; this.colVertices[i].verts[j] += clampedTranslation * surfaceDot * Mathf.Min(clampedColMag * 0.01f, distClamp) * massFactor; } } } } //Displace parts for (var i = 0; i < this.displaceParts.Length; i++) { curDisplacePart = this.displaceParts[i]; translation = clampedVel; clampedTranslation = Vector3.ClampMagnitude(translation, clampedColMag); if (translation.sqrMagnitude > 0 && this.strength < 1) { vertDist = Vector3.Distance(curDisplacePart.position, damagePoint); distClamp = (clampedColMag * 0.001f) / Mathf.Pow(vertDist, clampedColMag); if (distClamp > 0.001f) { curDisplacePart.position += clampedTranslation * surfaceDot * Mathf.Min(clampedColMag * 0.01f, distClamp) * massFactor; //Detach detachable parts if (curDisplacePart.GetComponent <DetachablePart>()) { detachedPart = curDisplacePart.GetComponent <DetachablePart>(); if (colMag * surfaceDot * massFactor > detachedPart.looseForce && detachedPart.looseForce >= 0) { detachedPart.initialPos = curDisplacePart.localPosition; detachedPart.Detach(true); } else if (colMag * surfaceDot * massFactor > detachedPart.breakForce) { detachedPart.Detach(false); } } //Maybe the parent of this part is what actually detaches, useful for displacing compound colliders that represent single detachable objects else if (curDisplacePart.parent.GetComponent <DetachablePart>()) { detachedPart = curDisplacePart.parent.GetComponent <DetachablePart>(); if (!detachedPart.detached) { if (colMag * surfaceDot * massFactor > detachedPart.looseForce && detachedPart.looseForce >= 0) { detachedPart.initialPos = curDisplacePart.parent.localPosition; detachedPart.Detach(true); } else if (colMag * surfaceDot * massFactor > detachedPart.breakForce) { detachedPart.Detach(false); } } else if (detachedPart.hinge) { detachedPart.displacedAnchor += curDisplacePart.parent.InverseTransformDirection(clampedTranslation * surfaceDot * Mathf.Min(clampedColMag * 0.01f, distClamp) * massFactor); } } //Damage suspensions and wheels damagedSus = curDisplacePart.GetComponent <Suspension.Suspension>(); if (damagedSus) { if ((!damagedSus.wheel.grounded && this.ignoreGroundedWheels) || !this.ignoreGroundedWheels) { curDisplacePart.RotateAround(damagedSus.tr.TransformPoint(damagedSus.damagePivot), Vector3.ProjectOnPlane(damagePoint - curDisplacePart.position, -translation.normalized), clampedColMag * surfaceDot * distClamp * 20 * massFactor); damagedSus.wheel.damage += clampedColMag * surfaceDot * distClamp * 10 * massFactor; if (clampedColMag * surfaceDot * distClamp * 10 * massFactor > damagedSus.jamForce) { damagedSus.jammed = true; } if (clampedColMag * surfaceDot * distClamp * 10 * massFactor > damagedSus.wheel.detachForce) { damagedSus.wheel.Detach(); } foreach (var curPart in damagedSus.movingParts) { if (curPart.connectObj && !curPart.isHub && !curPart.solidAxle) { if (!curPart.connectObj.GetComponent <SuspensionPart>()) { curPart.connectPoint += curPart.connectObj.InverseTransformDirection(clampedTranslation * surfaceDot * Mathf.Min(clampedColMag * 0.01f, distClamp) * massFactor); } } } } } //Damage hover wheels var damagedHoverWheel = curDisplacePart.GetComponent <HoverWheel>(); if (damagedHoverWheel) { if ((!damagedHoverWheel.grounded && this.ignoreGroundedWheels) || !this.ignoreGroundedWheels) { if (clampedColMag * surfaceDot * distClamp * 10 * massFactor > damagedHoverWheel.detachForce) { damagedHoverWheel.Detach(); } } } } } } }
public override void updateFigure() { //update logic Vector3 norm1 = Vector3.right; Vector3 norm2 = Vector3.forward; Vector3.OrthoNormalize(ref normalDirection, ref norm1, ref norm2); float radius1 = Vector3.Magnitude(Vector3.ProjectOnPlane(endpoint1 - centerPoint, normalDirection)); float radius2 = Vector3.Magnitude(Vector3.ProjectOnPlane(endpoint2 - centerPoint, normalDirection)); Vector3 ps1a = Vector3.ProjectOnPlane(endpoint1 - centerPoint, normalDirection); Vector3 ps2a = Vector3.ProjectOnPlane(endpoint2 - centerPoint, normalDirection); //Find the phase shift using the angle between the projection of radius on the plane normal to the circle, //with the sign determined by the cross product of one of the basis vecs for the plane and the projected radius. float PhaseShift1 = Mathf.Deg2Rad * (Vector3.Angle(norm1, ps1a)) * Mathf.Sign(Vector3.Dot(Vector3.Cross(norm1, ps1a), normalDirection)) + phaseshiftAdjust; //Debug.Log(PhaseShift1); float PhaseShift2 = Mathf.Deg2Rad * (Vector3.Angle(norm1, ps2a)) * Mathf.Sign(Vector3.Dot(Vector3.Cross(norm1, ps2a), normalDirection)) + phaseshiftAdjust; //find phase shift by converting from cartesian to //float PhaseShift1 = Mathf.Atan2(Vector3.Magnitude(Vector3.Project(ps1a, norm1)), Vector3.Magnitude(Vector3.Project(ps1a, norm2))) - Mathf.PI / 2; //float PhaseShift2 = Mathf.Atan2(Vector3.Magnitude(Vector3.Project(ps2a, norm1)), Vector3.Magnitude(Vector3.Project(ps2a, norm2))) - Mathf.PI / 2; MeshFilter mf = GetComponent <MeshFilter>(); Mesh mesh = mf.mesh; Vector3[] vertices = mesh.vertices; for (int i = 0; i < n; i++) { vertices[i] = LocalPosition(radius1 * (Mathf.Sin(PhaseShift1 + (i * Mathf.PI * 2 / n)) * norm1) + radius1 * (Mathf.Cos(PhaseShift1 + (i * Mathf.PI * 2 / n)) * norm2) + Vector3.Project(endpoint1 - centerPoint, normalDirection)); vertices[i + n] = LocalPosition(radius2 * (Mathf.Sin(PhaseShift2 + (i * Mathf.PI * 2 / n)) * norm1) + radius2 * (Mathf.Cos(PhaseShift2 + (i * Mathf.PI * 2 / n)) * norm2) + Vector3.Project(endpoint2 - centerPoint, normalDirection)); } mesh.vertices = vertices; }
public static Mesh BuildMeshFromWythoffPoly(WythoffPoly source, Color[] colors) { if (colors == null) { colors = DefaultFaceColors; } var meshVertices = new List <Vector3>(); var meshTriangles = new List <int>(); var MeshVertexToVertex = new List <int>(); // Mapping of mesh vertices to poly vertices (one to many as we duplicate verts) var meshColors = new List <Color>(); var meshUVs = new List <Vector2>(); var mesh = new Mesh(); int meshVertexIndex = 0; foreach (Wythoff.Face face in source.faces) { face.CalcTriangles(); } for (int faceType = 0; faceType < source.FaceTypeCount; faceType++) { foreach (Wythoff.Face face in source.faces) { if (face.configuration == source.FaceSidesByType[faceType]) { var v0 = source.Vertices[face.points[0]].getVector3(); var v1 = source.Vertices[face.points[1]].getVector3(); var v2 = source.Vertices[face.points[2]].getVector3(); var normal = Vector3.Cross(v1 - v0, v2 - v0); var c = face.center.getVector3(); var yAxis = c - v0; var xAxis = Vector3.Cross(yAxis, normal); var faceColor = colors[(int)((face.configuration + 2) % colors.Length)]; // Vertices for (int i = 0; i < face.triangles.Length; i++) { Vector3 vcoords = source.Vertices[face.triangles[i]].getVector3(); meshVertices.Add(vcoords); meshColors.Add(faceColor); var u = Vector3.Project(vcoords, xAxis).magnitude; var v = Vector3.Project(vcoords, yAxis).magnitude; meshUVs.Add(new Vector2(u, v)); meshTriangles.Add(meshVertexIndex); MeshVertexToVertex.Add(face.triangles[i]); meshVertexIndex++; } } } } mesh.vertices = meshVertices.ToArray(); mesh.triangles = meshTriangles.ToArray(); mesh.colors = meshColors.ToArray(); mesh.uv = meshUVs.ToArray(); mesh.RecalculateNormals(); mesh.RecalculateTangents(); mesh.RecalculateBounds(); return(mesh); }
static Vector3 ResizeHandlesGUI(Rect rect, Vector3 pivot, Quaternion rotation, out Vector3 scalePivot) { if (Event.current.type == EventType.MouseDown) { s_StartRect = rect; } scalePivot = pivot; Vector3 scale = Vector3.one; Quaternion inverseRotation = Quaternion.Inverse(rotation); // Loop through the 8 handles (sides and corners) using a nested loop. // (The loop covers 9 combinations, but the center position is ignored.) for (int xHandle = 0; xHandle <= 2; xHandle++) { for (int yHandle = 0; yHandle <= 2; yHandle++) { // Ignore center if (xHandle == 1 && yHandle == 1) { continue; } Vector3 origPos = GetRectPointInWorld(s_StartRect, pivot, rotation, xHandle, yHandle); Vector3 curPos = GetRectPointInWorld(rect, pivot, rotation, xHandle, yHandle); float size = 0.05f * HandleUtility.GetHandleSize(curPos); int id = GUIUtility.GetControlID(s_ResizeHandlesHash, FocusType.Passive); if (GUI.color.a > 0 || GUIUtility.hotControl == id) { EditorGUI.BeginChangeCheck(); Vector3 newPos; EventType typeBefore = Event.current.type; if (xHandle == 1 || yHandle == 1) { // Side resizer (1D) Vector3 sideDir = (xHandle == 1 ? rotation * Vector3.right * rect.width : rotation * Vector3.up * rect.height); Vector3 slideDir = (xHandle == 1 ? rotation * Vector3.up : rotation * Vector3.right); newPos = RectHandles.SideSlider(id, curPos, sideDir, slideDir, size, null, 0); } else { // Corner handle (2D) Vector3 outwardsA = rotation * Vector3.right * (xHandle - 1); Vector3 outwardsB = rotation * Vector3.up * (yHandle - 1); newPos = RectHandles.CornerSlider(id, curPos, rotation * Vector3.forward, outwardsA, outwardsB, size, RectHandles.RectScalingHandleCap, Vector2.zero); } // Calculate snapping values if applicable bool supportsRectSnapping = Selection.transforms.Length == 1 && UnityEditorInternal.InternalEditorUtility.SupportsRectLayout(Selection.activeTransform) && Selection.activeTransform.parent.rotation == rotation; if (supportsRectSnapping) { Transform transform = Selection.activeTransform; RectTransform rectTransform = transform.GetComponent <RectTransform>(); Transform transformParent = transform.parent; RectTransform rectTransformParent = transformParent.GetComponent <RectTransform>(); if (typeBefore == EventType.MouseDown && Event.current.type != EventType.MouseDown) { RectTransformSnapping.CalculateOffsetSnapValues(transformParent, transform, rectTransformParent, rectTransform, xHandle, yHandle); } } if (EditorGUI.EndChangeCheck()) { // Resize handles require more fine grained rounding of values than other tools. // With other tools, the slight rounding is not notizable as long as it's just sub-pixel, // because the manipulated object is being moved at the same time. // However, with resize handles, when dragging one edge or corner, // the opposite is standing still, and even slight rounding can cause shaking/vibration. // At a fraction of the normal rounding, the shaking is very unlikely to happen though. ManipulationToolUtility.SetMinDragDifferenceForPos(curPos, 0.1f); if (supportsRectSnapping) { Transform transformParent = Selection.activeTransform.parent; RectTransform rectParent = transformParent.GetComponent <RectTransform>(); Vector2 snapSize = Vector2.one * HandleUtility.GetHandleSize(newPos) * RectTransformSnapping.kSnapThreshold; snapSize.x /= (inverseRotation * transformParent.TransformVector(Vector3.right)).x; snapSize.y /= (inverseRotation * transformParent.TransformVector(Vector3.up)).y; Vector3 newPosInParent = transformParent.InverseTransformPoint(newPos) - (Vector3)rectParent.rect.min; Vector3 newPosInParentSnapped = (Vector3)RectTransformSnapping.SnapToGuides(newPosInParent, snapSize) + Vector3.forward * newPosInParent.z; ManipulationToolUtility.DisableMinDragDifferenceBasedOnSnapping(newPosInParent, newPosInParentSnapped); newPos = transformParent.TransformPoint(newPosInParentSnapped + (Vector3)rectParent.rect.min); } bool scaleFromPivot = Event.current.alt; bool squashing = EditorGUI.actionKey; bool uniformScaling = Event.current.shift && !squashing; if (!scaleFromPivot) { scalePivot = GetRectPointInWorld(s_StartRect, pivot, rotation, 2 - xHandle, 2 - yHandle); } if (uniformScaling) { newPos = Vector3.Project(newPos - scalePivot, origPos - scalePivot) + scalePivot; } Vector3 sizeBefore = inverseRotation * (origPos - scalePivot); Vector3 sizeAfter = inverseRotation * (newPos - scalePivot); if (xHandle != 1) { scale.x = sizeAfter.x / sizeBefore.x; } if (yHandle != 1) { scale.y = sizeAfter.y / sizeBefore.y; } if (uniformScaling) { float refScale = (xHandle == 1 ? scale.y : scale.x); scale = Vector3.one * refScale; } if (squashing && xHandle == 1) { if (Event.current.shift) { scale.x = scale.z = 1 / Mathf.Sqrt(Mathf.Max(scale.y, 0.0001f)); } else { scale.x = 1 / Mathf.Max(scale.y, 0.0001f); } } if (uniformScaling) { float refScale = (xHandle == 1 ? scale.y : scale.x); scale = Vector3.one * refScale; } if (squashing && xHandle == 1) { if (Event.current.shift) { scale.x = scale.z = 1 / Mathf.Sqrt(Mathf.Max(scale.y, 0.0001f)); } else { scale.x = 1 / Mathf.Max(scale.y, 0.0001f); } } if (squashing && yHandle == 1) { if (Event.current.shift) { scale.y = scale.z = 1 / Mathf.Sqrt(Mathf.Max(scale.x, 0.0001f)); } else { scale.y = 1 / Mathf.Max(scale.x, 0.0001f); } } } if (xHandle == 0) { ManipulationToolUtility.DetectDraggingBasedOnMouseDownUp(kChangingLeft, typeBefore); } if (xHandle == 2) { ManipulationToolUtility.DetectDraggingBasedOnMouseDownUp(kChangingRight, typeBefore); } if (xHandle != 1) { ManipulationToolUtility.DetectDraggingBasedOnMouseDownUp(kChangingWidth, typeBefore); } if (yHandle == 0) { ManipulationToolUtility.DetectDraggingBasedOnMouseDownUp(kChangingBottom, typeBefore); } if (yHandle == 2) { ManipulationToolUtility.DetectDraggingBasedOnMouseDownUp(kChangingTop, typeBefore); } if (yHandle != 1) { ManipulationToolUtility.DetectDraggingBasedOnMouseDownUp(kChangingHeight, typeBefore); } } } } return(scale); }
// new Color(1.0f, 0.75f, 0.75f), // new Color(1.0f, 0.5f, 0.5f), // new Color(0.8f, 0.4f, 0.4f), // new Color(0.8f, 0.8f, 0.8f), // new Color(0.5f, 0.6f, 0.6f), // new Color(0.6f, 0.0f, 0.0f), // new Color(1.0f, 1.0f, 1.0f), // new Color(0.6f, 0.6f, 0.6f), // new Color(0.5f, 1.0f, 0.5f), // new Color(0.5f, 0.5f, 1.0f), // new Color(0.5f, 1.0f, 1.0f), // new Color(1.0f, 0.5f, 1.0f), public static Mesh BuildMeshFromConwayPoly( ConwayPoly conway, bool generateSubmeshes = false, Color[] colors = null, PolyHydraEnums.ColorMethods colorMethod = PolyHydraEnums.ColorMethods.ByRole, PolyHydraEnums.UVMethods uvMethod = PolyHydraEnums.UVMethods.FirstEdge, bool largeMeshFormat = true ) { Vector2 calcUV(Vector3 point, Vector3 xAxis, Vector3 yAxis) { float u, v; u = Vector3.Project(point, xAxis).magnitude; u *= Vector3.Dot(point, xAxis) > 0 ? 1 : -1; v = Vector3.Project(point, yAxis).magnitude; v *= Vector3.Dot(point, yAxis) > 0 ? 1 : -1; return(new Vector2(u, v)); } if (colors == null) { colors = DefaultFaceColors; } var target = new Mesh(); if (largeMeshFormat) { target.indexFormat = IndexFormat.UInt32; } var meshTriangles = new List <int>(); var meshVertices = new List <Vector3>(); var meshNormals = new List <Vector3>(); var meshColors = new List <Color32>(); var meshUVs = new List <Vector2>(); var edgeUVs = new List <Vector2>(); var barycentricUVs = new List <Vector3>(); var miscUVs1 = new List <Vector4>(); var miscUVs2 = new List <Vector4>(); List <ConwayPoly.Roles> uniqueRoles = null; List <int> uniqueSides = null; List <string> uniqueTags = null; var submeshTriangles = new List <List <int> >(); // TODO // var hasNaked = conway.HasNaked(); // Strip down to Face-Vertex structure var points = conway.ListVerticesByPoints(); var faceIndices = conway.ListFacesByVertexIndices(); // Add faces int index = 0; if (generateSubmeshes) { switch (colorMethod) { case PolyHydraEnums.ColorMethods.ByRole: uniqueRoles = new HashSet <ConwayPoly.Roles>(conway.FaceRoles).ToList(); for (int i = 0; i < uniqueRoles.Count; i++) { submeshTriangles.Add(new List <int>()); } break; case PolyHydraEnums.ColorMethods.BySides: for (int i = 0; i < colors.Length; i++) { submeshTriangles.Add(new List <int>()); } break; case PolyHydraEnums.ColorMethods.ByFaceDirection: for (int i = 0; i < colors.Length; i++) { submeshTriangles.Add(new List <int>()); } break; case PolyHydraEnums.ColorMethods.ByTags: var flattenedTags = conway.FaceTags.SelectMany(d => d.Select(i => i.Item1)); uniqueTags = new HashSet <string>(flattenedTags).ToList(); for (int i = 0; i < uniqueTags.Count + 1; i++) { submeshTriangles.Add(new List <int>()); } break; } } for (var i = 0; i < faceIndices.Length; i++) { var faceIndex = faceIndices[i]; var face = conway.Faces[i]; var faceNormal = face.Normal; var faceCentroid = face.Centroid; ConwayPoly.Roles faceRole = conway.FaceRoles[i]; // Axes for UV mapping Vector3 xAxis = Vector3.right; Vector3 yAxis = Vector3.up; switch (uvMethod) { case PolyHydraEnums.UVMethods.FirstEdge: xAxis = face.Halfedge.Vector; yAxis = Vector3.Cross(xAxis, faceNormal); break; case PolyHydraEnums.UVMethods.BestEdge: xAxis = face.GetBestEdge().Vector; yAxis = Vector3.Cross(xAxis, faceNormal); break; case PolyHydraEnums.UVMethods.FirstVertex: yAxis = face.Centroid - face.GetVertices()[0].Position; xAxis = Vector3.Cross(yAxis, faceNormal); break; case PolyHydraEnums.UVMethods.BestVertex: yAxis = face.Centroid - face.GetBestEdge().Vertex.Position; xAxis = Vector3.Cross(yAxis, faceNormal); break; case PolyHydraEnums.UVMethods.ObjectAligned: // Align towards the highest vertex or edge midpoint (measured in the y direction) Vertex chosenVert = face.GetVertices().OrderBy(vert => vert.Position.y).First(); Halfedge chosenEdge = face.GetHalfedges().OrderBy(edge => edge.Midpoint.y).First(); Vector3 chosenPoint; if (chosenVert.Position.y > chosenEdge.Midpoint.y + 0.01f) // favour edges slightly { chosenPoint = chosenVert.Position; } else { chosenPoint = chosenEdge.Midpoint; } yAxis = face.Centroid - chosenPoint; xAxis = Vector3.Cross(yAxis, faceNormal); break; } Color32 color = CalcFaceColor(conway, colors, colorMethod, i); float faceScale = 0; foreach (var v in face.GetVertices()) { faceScale += Vector3.Distance(v.Position, faceCentroid); } faceScale /= face.Sides; var miscUV1 = new Vector4(faceScale, face.Sides, faceCentroid.magnitude, ((float)i) / faceIndices.Length); var miscUV2 = new Vector4(faceCentroid.x, faceCentroid.y, faceCentroid.z, i); var faceTris = new List <int>(); if (face.Sides > 3) { for (var edgeIndex = 0; edgeIndex < faceIndex.Count; edgeIndex++) { meshVertices.Add(faceCentroid); meshUVs.Add(calcUV(meshVertices[index], xAxis, yAxis)); faceTris.Add(index++); edgeUVs.Add(new Vector2(0, 0)); barycentricUVs.Add(new Vector3(0, 0, 1)); meshVertices.Add(points[faceIndex[edgeIndex]]); meshUVs.Add(calcUV(meshVertices[index], xAxis, yAxis)); faceTris.Add(index++); edgeUVs.Add(new Vector2(1, 1)); barycentricUVs.Add(new Vector3(0, 1, 0)); meshVertices.Add(points[faceIndex[(edgeIndex + 1) % face.Sides]]); meshUVs.Add(calcUV(meshVertices[index], xAxis, yAxis)); faceTris.Add(index++); edgeUVs.Add(new Vector2(1, 1)); barycentricUVs.Add(new Vector3(1, 0, 0)); meshNormals.AddRange(Enumerable.Repeat(faceNormal, 3)); meshColors.AddRange(Enumerable.Repeat(color, 3)); miscUVs1.AddRange(Enumerable.Repeat(miscUV1, 3)); miscUVs2.AddRange(Enumerable.Repeat(miscUV2, 3)); } } else { meshVertices.Add(points[faceIndex[0]]); meshUVs.Add(calcUV(meshVertices[index], xAxis, yAxis)); faceTris.Add(index++); barycentricUVs.Add(new Vector3(0, 0, 1)); meshVertices.Add(points[faceIndex[1]]); meshUVs.Add(calcUV(meshVertices[index], xAxis, yAxis)); faceTris.Add(index++); barycentricUVs.Add(new Vector3(0, 1, 0)); meshVertices.Add(points[faceIndex[2]]); meshUVs.Add(calcUV(meshVertices[index], xAxis, yAxis)); faceTris.Add(index++); barycentricUVs.Add(new Vector3(1, 0, 0)); edgeUVs.AddRange(Enumerable.Repeat(new Vector2(1, 1), 3)); meshNormals.AddRange(Enumerable.Repeat(faceNormal, 3)); meshColors.AddRange(Enumerable.Repeat(color, 3)); miscUVs1.AddRange(Enumerable.Repeat(miscUV1, 3)); miscUVs2.AddRange(Enumerable.Repeat(miscUV2, 3)); } if (generateSubmeshes) { switch (colorMethod) { case PolyHydraEnums.ColorMethods.ByRole: int uniqueRoleIndex = uniqueRoles.IndexOf(faceRole); submeshTriangles[uniqueRoleIndex].AddRange(faceTris); break; case PolyHydraEnums.ColorMethods.BySides: submeshTriangles[face.Sides].AddRange(faceTris); break; case PolyHydraEnums.ColorMethods.ByFaceDirection: submeshTriangles[CalcDirectionIndex(face, colors.Length - 1)].AddRange(faceTris); break; case PolyHydraEnums.ColorMethods.ByTags: if (conway.FaceTags[i].Count > 0) { string htmlColor = conway.FaceTags[i].First(t => t.Item1.StartsWith("#")).Item1; int uniqueTagIndex = uniqueTags.IndexOf(htmlColor); submeshTriangles[uniqueTagIndex + 1].AddRange(faceTris); } else { submeshTriangles[0].AddRange(faceTris); } break; } } else { meshTriangles.AddRange(faceTris); } } target.vertices = meshVertices.Select(x => Jitter(x)).ToArray(); target.normals = meshNormals.ToArray(); if (generateSubmeshes) { target.subMeshCount = submeshTriangles.Count; for (var i = 0; i < submeshTriangles.Count; i++) { target.SetTriangles(submeshTriangles[i], i); } } else { target.triangles = meshTriangles.ToArray(); } target.colors32 = meshColors.ToArray(); target.SetUVs(0, meshUVs); target.SetUVs(1, edgeUVs); target.SetUVs(2, barycentricUVs); target.SetUVs(3, miscUVs1); target.SetUVs(4, miscUVs2); target.RecalculateTangents(); return(target); }
void RotateJoint(int bone) { //if blendWeight is 0 there is no need to compute the rotations if (blendWeight <= 0) { return; } Vector3 upDir = new Vector3(); Vector3 rightDir = new Vector3(); if (bone == (int)Kinect.NuiSkeletonPositionIndex.Spine) { upDir = ((Hip_Left.transform.position + Hip_Right.transform.position) / 2F) - Hip_Override.transform.position; rightDir = Hip_Right.transform.position - Hip_Left.transform.position; } //if the model is not animated, reset rotations to fix twisted joints if (!animated) { _bones[bone].transform.localRotation = _baseRotation[bone]; } //if the required bone data from the kinect isn't available, return if (sw.boneState[player, bone] == Kinect.NuiSkeletonPositionTrackingState.NotTracked) { return; } //get the target direction of the bone in world space //for the majority of bone it's bone - 1 to bone, but Hip_Override and the outside //shoulders are determined differently. Vector3 dir = _boneDir[bone]; Vector3 target; //if bone % 4 == 0 then it is either an outside shoulder or the hip override if (bone % 4 == 0) { //hip override is at Hip_Left if (bone == (int)Kinect.NuiSkeletonPositionIndex.HipLeft) { //target = vector from hip_center to average of hips left and right target = ((sw.bonePos[player, (int)Kinect.NuiSkeletonPositionIndex.HipLeft] + sw.bonePos[player, (int)Kinect.NuiSkeletonPositionIndex.HipRight]) / 2F) - sw.bonePos[player, (int)Kinect.NuiSkeletonPositionIndex.HipCenter]; } //otherwise it is one of the shoulders else { //target = vector from shoulder_center to bone target = sw.bonePos[player, bone] - sw.bonePos[player, (int)Kinect.NuiSkeletonPositionIndex.ShoulderCenter]; } } else { //target = vector from previous bone to bone target = sw.bonePos[player, bone] - sw.bonePos[player, bone - 1]; } //transform it into bone-local space (independant of the transform of the controller) target = transform.TransformDirection(target); target = _bones[bone].transform.InverseTransformDirection(target); //create a rotation that rotates dir into target Quaternion quat = Quaternion.FromToRotation(dir, target); //if bone is the spine, add in the rotation along the spine if (bone == (int)Kinect.NuiSkeletonPositionIndex.Spine) { //rotate the chest so that it faces forward (determined by the shoulders) dir = _chestRight; target = sw.bonePos[player, (int)Kinect.NuiSkeletonPositionIndex.ShoulderRight] - sw.bonePos[player, (int)Kinect.NuiSkeletonPositionIndex.ShoulderLeft]; target = transform.TransformDirection(target); target = _bones[bone].transform.InverseTransformDirection(target); target -= Vector3.Project(target, _boneDir[bone]); quat *= Quaternion.FromToRotation(dir, target); } //if bone is the hip override, add in the rotation along the hips else if (bone == (int)Kinect.NuiSkeletonPositionIndex.HipLeft) { //rotate the hips so they face forward (determined by the hips) dir = _hipRight; target = sw.bonePos[player, (int)Kinect.NuiSkeletonPositionIndex.HipRight] - sw.bonePos[player, (int)Kinect.NuiSkeletonPositionIndex.HipLeft]; target = transform.TransformDirection(target); target = _bones[bone].transform.InverseTransformDirection(target); target -= Vector3.Project(target, _boneDir[bone]); quat *= Quaternion.FromToRotation(dir, target); } //reduce the effect of the rotation using the blend parameter quat = Quaternion.Lerp(Quaternion.identity, quat, blendWeight); //apply the rotation to the local rotation of the bone _bones[bone].transform.localRotation = _bones[bone].transform.localRotation * quat; if (bone == (int)Kinect.NuiSkeletonPositionIndex.Spine) { restoreBone(_bones[(int)Kinect.NuiSkeletonPositionIndex.HipLeft], _boneDir[(int)Kinect.NuiSkeletonPositionIndex.HipLeft], upDir); restoreBone(_bones[(int)Kinect.NuiSkeletonPositionIndex.HipLeft], _hipRight, rightDir); } return; }
public void SendRadarData() { if (Bridge == null || Bridge.Status != Ros.Status.Connected) { return; } var apolloHeader = new Ros.ApolloHeader() { timestamp_sec = (System.DateTime.UtcNow - originTime).TotalSeconds, module_name = "conti_radar", sequence_num = seqId }; var radarPos = transform.position; var radarAim = transform.forward; var radarRight = transform.right; radarObjList.Clear(); utilColList.Clear(); utilColList.AddRange(radarDetectedColliders.Keys); utilColList.RemoveAll(c => c == null); //Debug.Log("radarDetectedColliders.Count: " + radarDetectedColliders.Count); System.Func <Collider, int> GetDynPropInt = ((col) => { var trafAiMtr = col.GetComponentInParent <TrafAIMotor>(); if (trafAiMtr != null) { return(trafAiMtr.currentSpeed > 1.0f ? 0 : 1); } return(1); }); System.Func <Collider, Vector3> GetLinVel = ((col) => { var trafAiMtr = col.GetComponentInParent <TrafAIMotor>(); if (trafAiMtr != null) { return(trafAiMtr.currentVelocity); } else { return(col.attachedRigidbody == null ? Vector3.zero : col.attachedRigidbody.velocity); } }); for (int i = 0; i < utilColList.Count; i++) { Collider col = utilColList[i]; Vector3 point = radarDetectedColliders[col].point; Vector3 relPos = point - radarPos; Vector3 carVel = gameObject.GetComponentInParent <Rigidbody>().velocity; Vector3 relVel = carVel - GetLinVel(col); //Debug.Log("id to be assigned to obstacle_id is " + radarDetectedColliders[col].id); BoxCollider boxCol = (BoxCollider)(col); Vector3 size = boxCol == null ? Vector3.zero : boxCol.size; // angle is orientation of the obstacle in degrees as seen by radar, counterclockwise is positive double angle = -Vector3.SignedAngle(transform.forward, col.transform.forward, transform.up); if (angle > 90) { angle -= 180; } else if (angle < -90) { angle += 180; } radarObjList.Add(new Ros.Apollo.Drivers.ContiRadarObs() { header = apolloHeader, clusterortrack = false, obstacle_id = radarDetectedColliders[col].id, longitude_dist = Vector3.Project(relPos, radarAim).magnitude, lateral_dist = Vector3.Project(relPos, radarRight).magnitude *(Vector3.Dot(relPos, radarRight) > 0 ? -1 : 1), longitude_vel = Vector3.Project(relVel, radarAim).magnitude *(Vector3.Dot(relVel, radarAim) > 0 ? -1 : 1), lateral_vel = Vector3.Project(relVel, radarRight).magnitude *(Vector3.Dot(relVel, radarRight) > 0 ? -1 : 1), rcs = 11.0, // dynprop = GetDynPropInt(col), // seem to be constant longitude_dist_rms = 0, lateral_dist_rms = 0, longitude_vel_rms = 0, lateral_vel_rms = 0, probexist = 1.0, //prob confidence meas_state = radarDetectedColliders[col].newDetection ? 1 : 2, //1 new 2 exist longitude_accel = 0, lateral_accel = 0, oritation_angle = angle, longitude_accel_rms = 0, lateral_accel_rms = 0, oritation_angle_rms = 0, length = size.z, width = size.x, obstacle_class = size.z > 5 ? 2 : 1, // 0: point; 1: car; 2: truck; 3: pedestrian; 4: motorcycle; 5: bicycle; 6: wide; 7: unknown }); } var msg = new Ros.Apollo.Drivers.ContiRadar { header = apolloHeader, contiobs = radarObjList, object_list_status = new Ros.Apollo.Drivers.ObjectListStatus_60A { nof_objects = utilColList.Count, meas_counter = 22800, interface_version = 0 } }; Bridge.Publish(ApolloTopicName, msg); ++seqId; }
public static Vector3 Reject(Vector3 a, Vector3 b) { return(a - Vector3.Project(a, b)); }
void ConstraintMovementDirection() { // If there is a movementDirection, capsuleCast in that direction to avoid the player to stick on walls and avoid small terrain variations. if (!Vector3Equal(movementDirection, Vector3.zero)) { capsulecastHitArray = OptimizedCapsuleCastFromPlayer(radiusScale, movementDirection.normalized, maximumMovementSpeed * Time.fixedDeltaTime, environmentLayerMask | enemiesLayerMask); // This value is used to mantain the input value after constraining the movementDirection. float oldMovementMagnitude = movementDirection.magnitude; //foreach (RaycastHit capsulecastHit in capsulecastHitArray) for (int i = capsulecastHitArray.Length - 1; i >= 0; i--) { if (capsulecastHitArray[i].collider.isTrigger) { continue; } //For colliders that overlap the capsule at the start of the sweep, to avoid problems. if (Vector3Equal(Vector3.zero, capsulecastHitArray[i].point)) { continue; } // If the capsulecast hit a wall/steep: // and the hit height is not allowed // or the normal is "pointing downwards" // or another capsule collider hits any object // or the character is jumping. // Constraint movementDirection if (capsulecastHitArray[i].normal.y <0 || Vector3.Angle(capsulecastHitArray[i].normal, Vector3.up)> steepAngle) { float distanceToGround = Mathf.Max(0f, Vector3.Project(capsulecastHitArray[i].point - (point2 - Vector3.up * radius), groundNormal).y); if (playerJumping || distanceToGround > stepMaxHeight || capsulecastHitArray[i].normal.y < 0 || Physics.CapsuleCast(point1 + Vector3.up * stepMaxHeight, point2 + Vector3.up * stepMaxHeight, radius, movementDirection.normalized, Mathf.Max(capsulecastHitArray[i].normal.y, stepMinDepth), environmentLayerMask | enemiesLayerMask)) { movementDirection -= Vector3.Project(movementDirection, Vector3.Scale(capsulecastHitArray[i].normal, new Vector3(1, 0, 1)).normalized); } else { if (playerGrounded) { playerRigidbody.MovePosition(playerRigidbody.position + Vector3.up * distanceToGround); playerRigidbody.velocity = new Vector3(playerRigidbody.velocity.x, 0f, playerRigidbody.velocity.z); break; } continue; } } else { if (playerGrounded) { // If the gameObject in front isn't a slope or wall, and the character isn't falling, just use its normal as floor normal. groundNormal = capsulecastHitArray[i].normal; groundAngle = Vector3.Angle(groundNormal, Vector3.up); // And project the movement Direction Again ProjectMovementDirection(); } continue; } } // This code is to enable movement direction readjust (not recommended for a platforms game) // If the new movementDirection isn't 0, scale the movementDirection vector. if (changeMovementDirectionOnCollision && !Vector3Equal(movementDirection, Vector3.zero)) { movementDirection *= oldMovementMagnitude / movementDirection.magnitude; } } }
public static Vector2 GenerateForce_Normal(Vector2 f_gravity, Vector2 surfaceNormal) { return(Vector3.Project(f_gravity, surfaceNormal.normalized)); }
void FixedUpdate() { TrackContacts(); float timeSinceLastGrounded = Time.fixedTime - lastGroundedTimestamp; bool readyToJump = Time.fixedTime - lastJumpTimestamp >= JumpCooldown; var move = new Vector3(MoveX, 0, MoveY); var m = collider.material; float moveAmount = move.magnitude; if (moveAmount != 0) { m.dynamicFriction = 0; m.frictionCombine = PhysicMaterialCombine.Average; m.dynamicFriction2 = SidewaysFriction; m.staticFriction2 = SidewaysFriction; m.frictionDirection2 = transform.InverseTransformDirection(Vector3.Cross(move, Vector3.up)); rigidbody.WakeUp(); var moveDir = move.normalized; if (moveAmount > 1) { moveAmount = 1; } var platformVelocity = Vector3.zero; var horzAccel = moveDir * moveAmount; var vertAccel = Vector3.up * moveAmount; if (IsGrounded) { var otherRigidbody = floorContact.otherCollider.attachedRigidbody; if (otherRigidbody != null) { platformVelocity = otherRigidbody.GetPointVelocity(floorContact.point); } if (PerformJump && readyToJump) { horzAccel *= JumpHorizontalAcceleration; // In this case vertical acceleration added by separate AddForce () call. } else { horzAccel *= HorizontalAcceleration; vertAccel *= VerticalAcceleration; } } else { horzAccel *= AirHorizontalAcceleration; vertAccel *= AirVerticalAcceleration; } var relVelocity = rigidbody.velocity - platformVelocity; var relHorzVelocity = new Vector3(relVelocity.x, 0, relVelocity.z); if (relHorzVelocity.magnitude > MaxVelocity) { var accelProj = Vector3.Project(horzAccel, relHorzVelocity.normalized); // TODO: is ".normalized" necessary? horzAccel -= accelProj; } var totalAccel = horzAccel + vertAccel; rigidbody.AddForce(totalAccel * totalBodyMass, ForceMode.Force); if (timeSinceLastGrounded < AirControlLossDelay || IsGrabbing) { maintainOrientationJoint.TargetRotation = Quaternion.RotateTowards( maintainOrientationJoint.TargetRotation, Quaternion.Inverse(Quaternion.LookRotation(moveDir)), RotateVelocity * Time.fixedDeltaTime ); } } else { m.dynamicFriction = IdleFriction; m.frictionCombine = PhysicMaterialCombine.Maximum; m.dynamicFriction2 = 0; m.staticFriction2 = 0; m.frictionDirection2 = Vector3.zero; } collider.material = m; if (PerformJump && IsGrounded && readyToJump) { var normalInPelvisCoords = transform.InverseTransformDirection(floorContact.normal); float jumpAmount = Mathf.Clamp01(Vector3.Dot(normalInPelvisCoords, Vector3.up)); if (jumpAmount > 0) { var accel = Vector3.up * JumpVerticalAcceleration * jumpAmount; rigidbody.AddForce(accel * totalBodyMass, ForceMode.Force); lastJumpTimestamp = Time.fixedTime; } } if (PerformCrouch) { MuscleTensionController.Relax(muscleTensionController, damperMultiplier: 0.01f); } else { if (IsGrounded || timeSinceLastGrounded < AirControlLossDelay) { MuscleTensionController.Stretch(muscleTensionController, useGravity: true); } else if (IsGrabbing) { MuscleTensionController.Stretch(muscleTensionController, 0.1f, 0.1f, useGravity: true); } else { MuscleTensionController.Relax(muscleTensionController, damperMultiplier: 0.1f); } } }
public void CalculateCameraMatrix(BoxCollider Box, Camera cam, bool bleft = true) { Vector3 dir = stereoCameraHead.transform.position - Box.transform.position; //dl -> dr -> ur -> rl clockwise points = Box.GetMinProjectBox(ref dir);// new Vector3[] {dl, dr, ur, ul }; Debug.DrawLine(cam.transform.position - dir, cam.transform.position, Color.yellow); Vector3 vecLeft, vecRight; Vector3 cameraUp = Vector3.up; float aspect = 0; for (int i = 0; i < 4; i++) { int iLeft = (i - 1 + 4) % 4; int iRight = (i + 1) % 4; vecLeft = points[iLeft] - points[i]; vecRight = points[iRight] - points[i]; float angle = Vector3.Angle(vecLeft, vecRight); if (angle < 90) { continue; } float lenLeft = vecLeft.magnitude; float lenRight = vecRight.magnitude; if (lenLeft > lenRight) { Vector3 vec = Vector3.Project(vecRight, vecLeft); points[i] = points[i] + vec; points[(i + 2) % 4] -= vec; cameraUp = points[iRight] - points[i]; vec = points[iLeft] - points[i]; aspect = vec.magnitude / cameraUp.magnitude; } else { Vector3 vec = Vector3.Project(vecLeft, vecRight); points[i] = points[i] + vec; points[(i + 2) % 4] -= vec; cameraUp = points[iLeft] - points[i]; vec = points[iRight] - points[i]; aspect = vec.magnitude / cameraUp.magnitude; } break; } cam.transform.rotation = Quaternion.LookRotation(-dir, cameraUp); //cam.transform.LookAt(-dir, cameraUp); //Vector3 vecDLtoDR = dl - dr; //Vector3 vecURtoDR = ur - dr; //float lenDLtoDR = vecDLtoDR.magnitude; //float lenURtoDR = vecURtoDR.magnitude; //if (lenDLtoDR > lenURtoDR) //{ // //base edge vecDLtoDR float fov = Mathf.Atan2(cameraUp.magnitude / 2, dir.magnitude) * 180 / Mathf.PI; cam.fieldOfView = fov * 2; cam.aspect = aspect; Matrix4x4 P = Matrix4x4.Perspective(fov * 2, aspect, 0.1f, 1000); Vector4 clipplane = CameraHelper.CameraSpacePlane(cam, Box.transform.position, -Box.transform.forward, 0.01f); Matrix4x4 clipP = P; CameraHelper.CalculateObliqueMatrix(ref clipP, clipplane); ///Matrix4x4 mat = Camera.main.projectionMatrix; cam.projectionMatrix = clipP; // = Camera.main.CalculateObliqueMatrix(clipplane); //calculate the mirror camera's vp //var mirrorVPMat = mat * Camera.main.worldToCameraMatrix; //var mirrorVPMat = mat.transpose;// * Camera.main.worldToCameraMatrix; Matrix4x4 V = cam.worldToCameraMatrix; P = GL.GetGPUProjectionMatrix(P, true); Matrix4x4 VP = P * V; if (bleft) { Box.GetComponentInChildren <Renderer>().material.SetVector("_matrix01", new Vector4(VP.m00, VP.m01, VP.m02, VP.m03)); Box.GetComponentInChildren <Renderer>().material.SetVector("_matrix02", new Vector4(VP.m10, VP.m11, VP.m12, VP.m13)); Box.GetComponentInChildren <Renderer>().material.SetVector("_matrix03", new Vector4(VP.m20, VP.m21, VP.m22, VP.m23)); Box.GetComponentInChildren <Renderer>().material.SetVector("_matrix04", new Vector4(VP.m30, VP.m31, VP.m32, VP.m33)); } else { Box.GetComponentInChildren <Renderer>().material.SetVector("_rmatrix01", new Vector4(VP.m00, VP.m01, VP.m02, VP.m03)); Box.GetComponentInChildren <Renderer>().material.SetVector("_rmatrix02", new Vector4(VP.m10, VP.m11, VP.m12, VP.m13)); Box.GetComponentInChildren <Renderer>().material.SetVector("_rmatrix03", new Vector4(VP.m20, VP.m21, VP.m22, VP.m23)); Box.GetComponentInChildren <Renderer>().material.SetVector("_rmatrix04", new Vector4(VP.m30, VP.m31, VP.m32, VP.m33)); } Box.GetComponentInChildren <Renderer>().material.SetFloat("_depth", dir.magnitude - 0.1f); }
//--------------------------------------------------------------------------------------------------- private void MoveSnapFace(float snapDist, float cornerSnap) { List <GameObject> list = BLOCK_COMP.PROXI_COLLIDER.closeBlocksColl; Vector3 moveVec2 = new Vector3(); if (list.Count > 0) { // Find shortest vector. float minDist = 1000; float cornerSnapDist = 1000; Vector3 closestEdge = new Vector3(); Vector3 closestEdgeProxi = new Vector3(); for (int i = 0; i < list.Count; i++) { List <object> snapList = Snap(i); Vector3 closeVec = (Vector3)snapList[1]; if (closeVec.magnitude < minDist) { minDist = closeVec.magnitude; moveVec2 = closeVec; } //-------------------------------------------------------------------------- // Find the closest edge of this obj and the coresponded closest edge of proxi obj that fits // the snapDist comparison. (This part is used in the Corner Snap only.) for (int j = 0; j < FACE_EDGE_MID_COLL.Length; j++) { Vector3 edgeMidThis = FACE_EDGE_MID_COLL[j]; //list[i].GetComponent<BlockPrim>().EDGE_MID_COLL.Length for (int h = 0; h < 4; h++) { Vector3 edgeMidProxi = list[i].GetComponent <BlockPrim>().EDGE_MID_COLL[h]; if ((edgeMidThis - edgeMidProxi).magnitude < cornerSnapDist) { cornerSnapDist = (edgeMidThis - edgeMidProxi).magnitude; closestEdge = edgeMidThis; closestEdgeProxi = list[i].GetComponent <BlockPrim>().EDGE_MID_COLL[h]; } } } } //print("mindist: " + Vector3.Project(moveVec2, FACE_NORMAL_WORLD).magnitude); //-------------------------------------------------------------------------- // 1. Corner snap has the most priority. if (cornerSnapDist < cornerSnap) { // Project the move vector on the face normal, to avoid shift and break the block right angles. Vector3 move = Vector3.Project(closestEdgeProxi - closestEdge, FACE_NORMAL_WORLD); //exactCornerSnap = true; MoveFace(BLOCK_COMP.ColliderName, move); //if (BLOCK_COMP.name == "Block" && this.name == "face_pos_z") print("Zero [" + "]: " + move.magnitude); return; } // 2. Apply face snap from this as priority. // Doesn't properly work. else if (Vector3.Project(moveVec2, FACE_NORMAL_WORLD).magnitude < snapDist) { // Specify the proxiIndex in order for Snap() to correctly calculate closest distance. Vector3 move = Vector3.Project(moveVec2, FACE_NORMAL_WORLD); //exactFaceSnap = true; MoveFace(BLOCK_COMP.ColliderName, move); //if (BLOCK_COMP.name == "Block" && this.name == "face_pos_z") print("First [" + "]: " + move.magnitude); return; } else { //print("No snap -2- !"); MoveFace(BLOCK_COMP.ColliderName); return; } } MoveFace(BLOCK_COMP.ColliderName); //print("No snap!"); }
public Vector3 Unproject(Vector3 vec, float viewportX, float viewportY, float viewportWidth, float viewportHeight) { float x = vec.X - viewportX; float y = GraphicsDevice.Viewport.Height - vec.Y - 1 - viewportY; vec = new Vector3((2 * x) / viewportWidth - 1, (2 * y) / viewportHeight - 1, 2 * vec.Z - 1); return vec.Project(InverseProjectionView); }
void DoVector3Operator() { var v1 = vector1.Value; var v2 = vector2.Value; switch (operation) { case Vector3Operation.DotProduct: storeFloatResult.Value = Vector3.Dot(v1, v2); break; case Vector3Operation.CrossProduct: storeVector3Result.Value = Vector3.Cross(v1, v2); break; case Vector3Operation.Distance: storeFloatResult.Value = Vector3.Distance(v1, v2); break; case Vector3Operation.Angle: storeFloatResult.Value = Vector3.Angle(v1, v2); break; case Vector3Operation.Project: storeVector3Result.Value = Vector3.Project(v1, v2); break; case Vector3Operation.Reflect: storeVector3Result.Value = Vector3.Reflect(v1, v2); break; case Vector3Operation.Add: storeVector3Result.Value = v1 + v2; break; case Vector3Operation.Subtract: storeVector3Result.Value = v1 - v2; break; case Vector3Operation.Multiply: var multResult = Vector3.zero; multResult.x = v1.x * v2.x; multResult.y = v1.y * v2.y; multResult.z = v1.z * v2.z; storeVector3Result.Value = multResult; break; case Vector3Operation.Divide: var divResult = Vector3.zero; divResult.x = v1.x / v2.x; divResult.y = v1.y / v2.y; divResult.z = v1.z / v2.z; storeVector3Result.Value = divResult; break; case Vector3Operation.Min: storeVector3Result.Value = Vector3.Min(v1, v2); break; case Vector3Operation.Max: storeVector3Result.Value = Vector3.Max(v1, v2); break; } }