예제 #1
0
 public bool OnSceneGUI(Transform transform, Color color, bool handlesOnly, ref Vector3 center, ref Vector3 size)
 {
   if (!this.m_UseLossyScale)
     return this.OnSceneGUI(transform.localToWorldMatrix, color, handlesOnly, ref center, ref size);
   Matrix4x4 transform1 = Matrix4x4.TRS(transform.position, transform.rotation, Vector3.one);
   size.Scale(transform.lossyScale);
   center = transform.TransformPoint(center);
   center = transform1.inverse.MultiplyPoint(center);
   bool flag = this.OnSceneGUI(transform1, color, handlesOnly, ref center, ref size);
   center = transform1.MultiplyPoint(center);
   center = transform.InverseTransformPoint(center);
   size.Scale(new Vector3(1f / transform.lossyScale.x, 1f / transform.lossyScale.y, 1f / transform.lossyScale.z));
   return flag;
 }
예제 #2
0
        public static bool UnityEngineVector3MCall(object objSelf, string functionName, List <CQ_Value> param, out CQ_Value returnValue, bool mustEqual)
        {
            UnityEngine.Vector3 obj = (UnityEngine.Vector3)objSelf;
            if (param.Count == 3 && functionName == "Set" && MatchType(param, new Type[] { typeof(float), typeof(float), typeof(float) }, mustEqual))
            {
                returnValue = null;
                obj.Set((float)param[0].ConvertTo(typeof(float)), (float)param[1].ConvertTo(typeof(float)), (float)param[2].ConvertTo(typeof(float)));
                return(true);
            }
            if (param.Count == 1 && functionName == "Scale" && MatchType(param, new Type[] { typeof(UnityEngine.Vector3) }, mustEqual))
            {
                returnValue = null;
                obj.Scale((UnityEngine.Vector3)param[0].ConvertTo(typeof(UnityEngine.Vector3)));
                return(true);
            }
            if (param.Count == 0 && functionName == "GetHashCode")
            {
                returnValue       = new CQ_Value();
                returnValue.type  = typeof(int);
                returnValue.value = obj.GetHashCode();
                return(true);
            }
            if (param.Count == 1 && functionName == "Equals" && MatchType(param, new Type[] { typeof(object) }, mustEqual))
            {
                returnValue       = new CQ_Value();
                returnValue.type  = typeof(bool);
                returnValue.value = obj.Equals((object)param[0].ConvertTo(typeof(object)));
                return(true);
            }
            if (param.Count == 0 && functionName == "Normalize")
            {
                returnValue = null;
                obj.Normalize();
                return(true);
            }
            if (param.Count == 0 && functionName == "ToString")
            {
                returnValue       = new CQ_Value();
                returnValue.type  = typeof(string);
                returnValue.value = obj.ToString();
                return(true);
            }
            if (param.Count == 1 && functionName == "ToString" && MatchType(param, new Type[] { typeof(string) }, mustEqual))
            {
                returnValue       = new CQ_Value();
                returnValue.type  = typeof(string);
                returnValue.value = obj.ToString((string)param[0].ConvertTo(typeof(string)));
                return(true);
            }
            if (param.Count == 0 && functionName == "GetType")
            {
                returnValue       = new CQ_Value();
                returnValue.type  = typeof(System.Type);
                returnValue.value = obj.GetType();
                return(true);
            }

            returnValue = null;
            return(false);
        }
    /// <summary>
    /// Within every frame, it checks if the game is still running and then calculates where the enemy has to move
    /// to get to the next way point, when the final way point is reached the enemy will be destroyed.
    /// </summary>
    protected new void Update()
    {
        base.Update();
        if (_gc.gameState == GameManager.GameState.Running)
        {
            var dir = Vector3.Scale(new Vector3(1, 0, 1), _target.position - transform.position);
            transform.Translate(dir.normalized * (speed * Time.deltaTime), Space.World);

            var position   = transform.position;
            var position2d = new Vector2(position.x, position.z);

            var targetPosition = _target.transform.position;
            var target2d       = new Vector2(targetPosition.x, targetPosition.z);

            if (Vector2.Distance(position2d, target2d) <= 0.1f)
            {
                if (_waypointIndex >= Waypoints.waypoints.Length)
                {
                    EndPointReached();
                }
                else
                {
                    NextWaypoint();
                }
            }
        }
    }
예제 #4
0
        private void ShowPickups()
        {
            foreach (var pickup in pickups)
            {
                Vector3 position = pickup.Position.GetVector3();
                Vector3 angle    = pickup.Angle.GetVector3();
                Vector3 scale    = pickup.Scale.GetVector3();
                scale.Scale(new Vector3(1.0f / 32.0f, 1.0f / 32.0f, 1.0f / 32.0f));
                angle.Scale(new Vector3(180f, 180f, 180f));
                position.y += scale.y / 2f;
                GameObject item;
                switch (pickup.ModelName)
                {
                case "crate_fruit":
                    item = Instantiate(fruitCrate, position, Quaternion.Euler(angle.x, angle.y, angle.z));
                    item.transform.localScale = scale;
                    break;

                case "crate_question":
                    item = Instantiate(itemCrate, position, Quaternion.Euler(angle.x, angle.y, angle.z));
                    item.transform.localScale = scale;
                    break;

                case "itemFruit":
                    item = Instantiate(itemFruit, position, Quaternion.Euler(angle.x, angle.y, angle.z));
                    item.transform.localScale = scale;
                    break;
                }
            }
        }
예제 #5
0
파일: MathExt.cs 프로젝트: sjschaff/rimlite
        public static Vec3 Scaled(this Vec3 v, Vec3 mult)
        {
            Vec3 ret = v;

            ret.Scale(mult);
            return(ret);
        }
예제 #6
0
    private void OnMouseDown()
    {
        if (_moving)
        {
            return;
        }
        if (_firingPosition)
        {
            if (_primed)
            {
                Fire();
            }
            return;
        }

        var o = PlayerController.Instance.Take("Gunpowder");

        if (o == null)
        {
            return;
        }

        FacilitatorScript.Instance.Hide();
        StartCoroutine(_moveCannon(firingPosition.position, Quaternion.Euler(Vector3.Scale(Quaternion.LookRotation(GameManager.Instance.EnemyPosition - transform.position).eulerAngles, Vector3.up)), MoveTime));
        _firingPosition = true;
        _primed         = true;
    }
예제 #7
0
        public void Execute(int index)
        {
            int triIndex = index * 3;

            var v1 = rotation * Vec3.Scale(vertices[triangles[triIndex]], localScale) + position;
            var v2 = rotation * Vec3.Scale(vertices[triangles[triIndex + 1]], localScale) + position;
            var v3 = rotation * Vec3.Scale(vertices[triangles[triIndex + 2]], localScale) + position;

            var tri = new Triangle(v1, v2, v3);

            // calculate the angle of this triangles resistance
            var cosAngle = Vec3.Dot(tri.Normal, -velocity) / (velocity.magnitude * tri.Normal.magnitude);
            var angle    = Mathf.Acos(cosAngle);

            // magnitude of drag: 180 = 1, 135 = 0.5, < 90 = 0
            angleMags[index] = Mathf.Clamp((angle - Mathf.PI / 2) / (Mathf.PI / 2), 0, 1);

            var velSqu = Mathf.Pow(velocity.magnitude, 2);

            if (useSimpleDrag)
            {
                dragForces[index] = -.5f * velSqu * tri.Area * (angleMags[index] * dragMulti) * Vec3.Normalize(velocity);
            }
            else
            {
                dragForces[index] = -.5f * velSqu * tri.Area * (angleMags[index] * dragMulti) * Vec3.Normalize(tri.Normal);
            }

            midpoints[index] = tri.Midpoint;
        }
예제 #8
0
    private Vector3 GetStartPointOfAirGrid()
    {
        var voxelSize    = Vector3.one * VoxelLength;
        var centerOfArea = Vector3.Scale(Size, voxelSize) / 2 - (voxelSize / 2);
        var startPoint   = transform.position - centerOfArea;

        return(startPoint);
    }
    /// <summary>
    /// Assigns velocity to particle b from particle a's kinetic energy
    /// </summary>
    /// <param name="a">Query particle</param>
    /// <param name="b">Collided particle</param>
    void Collide(ParticleGPU a, ParticleGPU b)
    {
        Vector3 energyAone = (1 / 2) * a.mass * Vector3.Scale(a.velocity, a.velocity);
        Vector3 energyBtwo = (1 / 2) * b.mass * Vector3.Scale(b.velocity, b.velocity);
        Vector3 squaredVel = (a.mass / b.mass) * Vector3.Scale(a.velocity, a.velocity);

        b.velocity = new Vector3(Mathf.Sqrt(squaredVel.x), Mathf.Sqrt(squaredVel.y), Mathf.Sqrt(squaredVel.z));
        SolvedVel  = b.velocity;
    }
예제 #10
0
        Vector3 ConvertPosWithoutOffset(int x, int y, int z)
        {
            Vector3 p = Vector3.Scale(
                new Vector3(
                    x,
                    y,
                    (z / (float)voxelArea.width)
                    )
                , cellScale)
                        + voxelOffset;

            return(p);
        }
예제 #11
0
        /** Convert from voxel coordinates to world coordinates.
         * (0,0,0) in voxel coordinates is a bottom corner of the bounding box.
         * (1,0,0) is one voxel in the +X direction of that.
         */
        public Vector3 VoxelToWorld(int x, int y, int z)
        {
            Vector3 p = Vector3.Scale(
                new Vector3(
                    x,
                    y,
                    z
                    )
                , cellScale)
                        + voxelOffset;

            return(p);
        }
예제 #12
0
        Vector3 ConvertPos(int x, int y, int z)
        {
            Vector3 p = Vector3.Scale(
                new Vector3(
                    x + 0.5F,
                    y,
                    (z / (float)voxelArea.width) + 0.5F
                    )
                , cellScale)
                        + voxelOffset;

            return(p);
        }
예제 #13
0
        public override Vector3 GetVectorField( Vector3 position )
        {
            position = position * noiseScale + offset;
            float angle = Mathf.Lerp( 0, 2 * Mathf.PI, Mathf.PerlinNoise(position.x, position.y) );
            Vector3 noiseVector  = new Vector3( Mathf.Cos(angle), Mathf.Sin(angle), 0 );

            //noiseVector = Random.onUnitSphere;

            noiseVector.Scale( new Vector3(affectX ? 1 : 0, affectY ? 1 : 0, affectZ ? 1: 0) );
            noiseVector *= force;

            return noiseVector;
        }
예제 #14
0
    static bool Vector3_Scale__Vector3(JSVCall vc, int argc)
    {
        int len = argc;

        if (len == 1)
        {
            UnityEngine.Vector3 arg0    = (UnityEngine.Vector3)JSApi.getVector3S((int)JSApi.GetType.Arg);
            UnityEngine.Vector3 argThis = (UnityEngine.Vector3)vc.csObj;        argThis.Scale(arg0);
            JSMgr.changeJSObj(vc.jsObjID, argThis);
        }

        return(true);
    }
예제 #15
0
 static public int Scale(IntPtr l)
 {
     try{
         UnityEngine.Vector3 self = (UnityEngine.Vector3)checkSelf(l);
         UnityEngine.Vector3 a1;
         checkType(l, 2, out a1);
         self.Scale(a1);
         setBack(l, self);
         return(0);
     }
     catch (Exception e) {
         LuaDLL.luaL_error(l, e.ToString());
         return(0);
     }
 }
예제 #16
0
        void CollectTreeMeshes(Terrain terrain, List <RasterizationMesh> result)
        {
            TerrainData data = terrain.terrainData;

            for (int i = 0; i < data.treeInstances.Length; i++)
            {
                TreeInstance  instance = data.treeInstances[i];
                TreePrototype prot     = data.treePrototypes[instance.prototypeIndex];

                // Make sure that the tree prefab exists
                if (prot.prefab == null)
                {
                    continue;
                }

                var collider     = prot.prefab.GetComponent <Collider>();
                var treePosition = terrain.transform.position + Vector3.Scale(instance.position, data.size);

                if (collider == null)
                {
                    var instanceBounds = new Bounds(terrain.transform.position + Vector3.Scale(instance.position, data.size), new Vector3(instance.widthScale, instance.heightScale, instance.widthScale));

                    Matrix4x4 matrix = Matrix4x4.TRS(treePosition, Quaternion.identity, new Vector3(instance.widthScale, instance.heightScale, instance.widthScale) * 0.5f);

                    var mesh = new RasterizationMesh(BoxColliderVerts, BoxColliderTris, instanceBounds, matrix);

                    result.Add(mesh);
                }
                else
                {
                    // The prefab has a collider, use that instead
                    var scale = new Vector3(instance.widthScale, instance.heightScale, instance.widthScale);

                    // Generate a mesh from the collider
                    RasterizationMesh mesh = RasterizeCollider(collider, Matrix4x4.TRS(treePosition, Quaternion.identity, scale));

                    // Make sure a valid mesh was generated
                    if (mesh != null)
                    {
                        // The bounds are incorrectly based on collider.bounds.
                        // It is incorrect because the collider is on the prefab, not on the tree instance
                        // so we need to recalculate the bounds based on the actual vertex positions
                        mesh.RecalculateBounds();
                        result.Add(mesh);
                    }
                }
            }
        }
예제 #17
0
 static int Scale(IntPtr L)
 {
     try
     {
         ToLua.CheckArgsCount(L, 2);
         UnityEngine.Vector3 obj  = (UnityEngine.Vector3)ToLua.CheckObject(L, 1, typeof(UnityEngine.Vector3));
         UnityEngine.Vector3 arg0 = (UnityEngine.Vector3)ToLua.CheckObject(L, 2, typeof(UnityEngine.Vector3));
         obj.Scale(arg0);
         ToLua.SetBack(L, 1, obj);
         return(0);
     }
     catch (Exception e)
     {
         return(LuaDLL.toluaL_exception(L, e));
     }
 }
예제 #18
0
        public void Dash()
        {
            if (Time.time > DashMark && _dashCount > 0)
            {
                DashMark = Time.time + DashTimeout;
                Source.PlayOneShot(DashAudioClip);

                _moveDirection += Vector3.Scale(_moveDirection.normalized,
                                                DashDistance * new Vector3((Mathf.Log(1f / (Time.deltaTime * Drag.x + 1)) / -Time.deltaTime),
                                                                           0,
                                                                           (Mathf.Log(1f / (Time.deltaTime * Drag.z + 1)) / -Time.deltaTime)));

                if (!_characterController.isGrounded)
                {
                    _moveDirection.y += _jumpSpeed / 2;
                }
            }
        }
예제 #19
0
        private void FixedUpdate()
        {
            if (IsFrozen)
            {
                m_CharacterMovement.Move(new Vector3(0, 0, 0));
                return;
            }

            var horizontal = Input.GetAxis("Horizontal");
            var vertical   = Input.GetAxis("Vertical");

            var camForward = Vector3.Scale(m_Camera.forward, new Vector3(1, 0, 1));
            var camRight   = Vector3.Scale(m_Camera.right, new Vector3(1, 0, 1));
            var movement   = vertical * camForward + horizontal * camRight;

            if (!IsRunning && !Input.GetKey(KeyCode.LeftShift) && !Input.GetKey(KeyCode.RightShift))
            {
                movement *= 0.6f;
            }

            m_CharacterMovement.Move(movement);
        }
예제 #20
0
        public override Vector3 GetVectorField( Vector3 position )
        {
            BoxCollider boxCollider = GetComponent<BoxCollider>();

            Vector3 affect = new Vector3(affectX ? 1 : 0, affectY ? 1 : 0, affectZ ? 1: 0);
            Vector3 vector = transform.position - position;
            vector.Scale( affect );

            vector.Normalize();

            Vector3 dist = transform.position - position;
            Vector3 halfSize = 0.5f * boxCollider.size;
            Vector3 attenuate = new Vector3( Mathf.Abs(dist.x) / halfSize.x, Mathf.Abs(dist.y)/halfSize.y, Mathf.Abs(dist.z)/halfSize.z );
            //attenuate = new Vector3( 1/ attenuate.x, 1/attenuate.y, 1/attenuate.z );
            attenuate.Scale( affect );

            vector *= force;

            vector.Scale( attenuate );

            return vector;
        }
예제 #21
0
        void Init()
        {
            textMesh = gameObject.GetComponent<TextMesh>();

            shadow = (UnityEngine.GameObject)Instantiate(gameObject);

            DropShadow script = shadow.GetComponent<DropShadow>();
            script.enabled = false;

            Vector3 shiftPos = new Vector3(-0.2f, 0.2f, 0);
            shiftPos.Scale(transform.localScale);
            shadow.transform.parent = transform.parent;
            shadow.transform.localPosition = transform.localPosition - shiftPos;
            shadow.transform.localRotation = transform.localRotation;
            shadow.transform.localScale = transform.localScale;

            shadow.hideFlags = HideFlags.NotEditable;
            transform.parent = shadow.transform;
            MeshRenderer meshRenderer = GetComponent<MeshRenderer>();
            meshRenderer.sortingOrder = meshRenderer.sortingOrder + 1;

            shadowTextMesh = shadow.GetComponent<TextMesh>();
            shadowTextMesh.color = new Color(0, 0, 0, 0.5f);
        }
예제 #22
0
        public void Drive(FlightCtrlState s)
        {
            if (useSAS)
            {
                _requestedAttitude = attitudeGetReferenceRotation(attitudeReference) * attitudeTarget * Quaternion.Euler(90, 0, 0);
                if (!vessel.ActionGroups[KSPActionGroup.SAS])
                {
                    vessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true);
                    vessel.Autopilot.SAS.LockHeading(_requestedAttitude);
                    lastSAS = _requestedAttitude;
                }
                else if (Quaternion.Angle(lastSAS, _requestedAttitude) > 10)
                {
                    vessel.Autopilot.SAS.LockHeading(_requestedAttitude);
                    lastSAS = _requestedAttitude;
                }
                else
                {
                    vessel.Autopilot.SAS.LockHeading(_requestedAttitude, true);
                }

            }
            else
            {
                // Direction we want to be facing
                _requestedAttitude = attitudeGetReferenceRotation(attitudeReference) * attitudeTarget;
                Transform vesselTransform = vessel.ReferenceTransform;
                Quaternion delta = Quaternion.Inverse(Quaternion.Euler(90, 0, 0) * Quaternion.Inverse(vesselTransform.rotation) * _requestedAttitude);

                Vector3d deltaEuler = delta.DeltaEuler();

                // ( MoI / available torque ) factor:
                Vector3d NormFactor = Vector3d.Scale(vesselState.MoI, torque.Invert()).Reorder(132);

                // Find out the real shorter way to turn were we wan to.
                // Thanks to HoneyFox
                Vector3d tgtLocalUp = vesselTransform.transform.rotation.Inverse() * _requestedAttitude * Vector3d.forward;
                Vector3d curLocalUp = Vector3d.up;

                double turnAngle = Math.Abs(Vector3d.Angle(curLocalUp, tgtLocalUp));
                Vector2d rotDirection = new Vector2d(tgtLocalUp.x, tgtLocalUp.z);
                rotDirection = rotDirection.normalized * turnAngle / 180.0;

                // And the lowest roll
                // Thanks to Crzyrndm
                Vector3 normVec = Vector3.Cross(_requestedAttitude * Vector3.forward, vesselTransform.up);
                Quaternion targetDeRotated = Quaternion.AngleAxis((float)turnAngle, normVec) * _requestedAttitude;
                float rollError = Vector3.Angle(vesselTransform.right, targetDeRotated * Vector3.right) * Math.Sign(Vector3.Dot(targetDeRotated * Vector3.right, vesselTransform.forward));

                error = new Vector3d(
                    -rotDirection.y * Math.PI,
                    rotDirection.x * Math.PI,
                    rollError * Mathf.Deg2Rad
                    );

                error.Scale(_axisControl);

                Vector3d err = error + inertia.Reorder(132) / 2d;
                err = new Vector3d(
                    Math.Max(-Math.PI, Math.Min(Math.PI, err.x)),
                    Math.Max(-Math.PI, Math.Min(Math.PI, err.y)),
                    Math.Max(-Math.PI, Math.Min(Math.PI, err.z)));

                err.Scale(NormFactor);

                // angular velocity:
                Vector3d omega;
                omega.x = vessel.angularVelocity.x;
                omega.y = vessel.angularVelocity.z; // y <=> z
                omega.z = vessel.angularVelocity.y; // z <=> y
                omega.Scale(NormFactor);

                if (Tf_autoTune)
                    tuneTf(torque);
                setPIDParameters();

                // angular velocity limit:
                var Wlimit = new Vector3d(Math.Sqrt(NormFactor.x * Math.PI * kWlimit),
                                           Math.Sqrt(NormFactor.y * Math.PI * kWlimit),
                                           Math.Sqrt(NormFactor.z * Math.PI * kWlimit));

                pidAction = pid.Compute(err, omega, Wlimit);

                // deadband
                pidAction.x = Math.Abs(pidAction.x) >= deadband ? pidAction.x : 0.0f;
                pidAction.y = Math.Abs(pidAction.y) >= deadband ? pidAction.y : 0.0f;
                pidAction.z = Math.Abs(pidAction.z) >= deadband ? pidAction.z : 0.0f;

                // low pass filter,  wf = 1/Tf:
                Vector3d act = lastAct;
                act.x += (pidAction.x - lastAct.x) * (1.0 / ((TfV.x / TimeWarp.fixedDeltaTime) + 1.0));
                act.y += (pidAction.y - lastAct.y) * (1.0 / ((TfV.y / TimeWarp.fixedDeltaTime) + 1.0));
                act.z += (pidAction.z - lastAct.z) * (1.0 / ((TfV.z / TimeWarp.fixedDeltaTime) + 1.0));
                lastAct = act;

                SetFlightCtrlState(act, deltaEuler, s, 1);

                act = new Vector3d(s.pitch, s.yaw, s.roll);

                // Feed the control torque to the differential throttle
            }
        }
예제 #23
0
        public static void TestScaleBy()
        {
            const float floatScale = 4.8f;
            const float floatStart = 1.2f;
            float floatVal = floatStart;
            Ref<float> floatRef = new Ref<float>(
            () => floatVal,
            t => floatVal = t
            );

            const double doubleScale = 3.2;
            const double doubleStart = 9.2;
            double doubleVal = doubleStart;
            Ref<double> doubleRef = new Ref<double>(
            () => doubleVal,
            t => doubleVal = t
            );

            Vector2 vec2Scale = new Vector2(9.5f, 2.0f);
            Vector2 vec2Start = new Vector2(4.0f, 5.0f);
            Vector2 vec2Val = vec2Start;
            Ref<Vector2> vec2Ref = new Ref<Vector2>(
            () => vec2Val,
            t =>  vec2Val = t
            );

            Vector3 vec3Scale = new Vector3(4.0f, 19.0f, 2.0f);
            Vector3 vec3Start = new Vector3(92.0f, 0.5f, 34.0f);
            Vector3 vec3Val = vec3Start;
            Ref<Vector3> vec3Ref = new Ref<Vector3>(
            () =>  vec3Val,
            t => vec3Val = t
            );

            Vector4 vec4Scale = new Vector4(92.0f, 0.5f, 14.0f, 7.0f);
            Vector4 vec4Start = new Vector4(0.4f, 10.0f, 3.0f, 82.0f);
            Vector4 vec4Val = vec4Start;
            Ref<Vector4> vec4Ref = new Ref<Vector4>(
            () => vec4Val,
            t => vec4Val = t
            );

            CommandQueue queue = new CommandQueue();
            queue.Enqueue(
            Commands.Repeat(2,
                Commands.Sequence(
                    Commands.Parallel(
                        Commands.ScaleBy(floatRef, floatScale, 1.0),
                        Commands.ScaleBy(doubleRef, doubleScale, 1.0),
                        Commands.ScaleBy(vec2Ref, vec2Scale, 1.0),
                        Commands.ScaleBy(vec3Ref, vec3Scale, 1.0),
                        Commands.ScaleBy(vec4Ref, vec4Scale, 1.0)
                    ),
                    Commands.WaitForFrames(1)
                )
            )
            );

            queue.Update(0.2f);

            Vector2 vec2ExpectedScale = vec2Scale;
            Vector3 vec3ExpectedScale = vec3Scale;
            Vector4 vec4ExpectedScale = vec4Scale;
            vec2ExpectedScale.Scale(new Vector2(0.2f, 0.2f));
            vec3ExpectedScale.Scale(new Vector3(0.2f, 0.2f, 0.2f));
            vec4ExpectedScale.Scale(new Vector4(0.2f, 0.2f, 0.2f, 0.2f));
            vec2ExpectedScale += new Vector2(0.8f, 0.8f);
            vec3ExpectedScale += new Vector3(0.8f, 0.8f, 0.8f);
            vec4ExpectedScale += new Vector4(0.8f, 0.8f, 0.8f, 0.8f);
            vec2ExpectedScale.Scale(vec2Start);
            vec3ExpectedScale.Scale(vec3Start);
            vec4ExpectedScale.Scale(vec4Start);
            AreEqual(floatVal, floatStart * (0.8f + floatScale * 0.2f), 0.001f);
            AreEqual(doubleVal, doubleStart * (0.8 + doubleScale * 0.2), 0.001f);
            AreEqual(vec2Val, vec2ExpectedScale, 0.001f);
            AreEqual(vec3Val, vec3ExpectedScale, 0.001f);
            AreEqual(vec4Val, vec4ExpectedScale, 0.001f);

            queue.Update(0.8);
            vec2ExpectedScale = vec2Scale;
            vec3ExpectedScale = vec3Scale;
            vec4ExpectedScale = vec4Scale;
            vec2ExpectedScale.Scale(vec2Start);
            vec3ExpectedScale.Scale(vec3Start);
            vec4ExpectedScale.Scale(vec4Start);
            AreEqual(floatVal,  floatStart * floatScale, 0.001f);
            AreEqual(doubleVal,  doubleStart * doubleScale, 0.001f);
            AreEqual(vec2Val, vec2ExpectedScale, 0.001f);
            AreEqual(vec3Val, vec3ExpectedScale, 0.001f);
            AreEqual(vec4Val, vec4ExpectedScale, 0.001f);

            floatVal = floatStart;
            doubleVal = doubleStart;
            vec2Val = vec2Start;
            vec3Val = vec3Start;
            vec4Val = vec4Start;
            queue.Update(0.0);
            queue.Update(0.5);
            vec2ExpectedScale = vec2Scale;
            vec3ExpectedScale = vec3Scale;
            vec4ExpectedScale = vec4Scale;
            vec2ExpectedScale.Scale(new Vector2(0.5f, 0.5f));
            vec3ExpectedScale.Scale(new Vector3(0.5f, 0.5f, 0.5f));
            vec4ExpectedScale.Scale(new Vector4(0.5f, 0.5f, 0.5f, 0.5f));
            vec2ExpectedScale += new Vector2(0.5f, 0.5f);
            vec3ExpectedScale += new Vector3(0.5f, 0.5f, 0.5f);
            vec4ExpectedScale += new Vector4(0.5f, 0.5f, 0.5f, 0.5f);
            vec2ExpectedScale.Scale(vec2Start);
            vec3ExpectedScale.Scale(vec3Start);
            vec4ExpectedScale.Scale(vec4Start);
            AreEqual(floatVal, floatStart * (0.5f + floatScale * 0.5f), 0.001f);
            AreEqual(doubleVal, doubleStart * (0.5 + doubleScale * 0.5), 0.001f);
            AreEqual(vec2Val, vec2ExpectedScale, 0.001f);
            AreEqual(vec3Val, vec3ExpectedScale, 0.001f);
            AreEqual(vec4Val, vec4ExpectedScale, 0.001f);
        }
예제 #24
0
 public virtual void rescaleModel()
 {
     //transform.GetChild(0).GetChild(0).GetChild(0).localScale = new Vector3(radialFactor, radialFactor, stretchFactor);
     /*if (origScale.x < 0)
         origScale = transform.GetChild(0).GetChild(0).localScale;*/
     Vector3 scale = new Vector3(radialFactor, stretchFactor, radialFactor);
     scale.Scale(origScale);
     transform.GetChild(0).GetChild(0).localScale = scale;
 }
예제 #25
0
        protected override void onPartFixedUpdate()
        {
            if (mode == CargoMode.Idle)
            {
                 teleCount = 0;
                 jumpCount = 0;
                 approachCount = 0;
                 waitCount = 0;
            }
            if (mode == CargoMode.ReasonableWaitBeforeJump)
            {
                waitCount++;
                if (waitCount > 300)
                {
                    mode = CargoMode.JumpRequested;
                }
            }

            if (mode == CargoMode.HoldingPosition)
            {
                vessel.SetWorldVelocity(destination.GetVelocityOfDestination(vessel));
            }

            if (mode == CargoMode.AcceleratingTowardsDock)
            {
                int safeDistance = 50;
                if (destination.IsDestinationLanded())
                {
                    safeDistance = 50;
                }

                if (approachCount == 50)
                {
                    approachCount++;
                    originalVesselVelocity = vessel.obt_velocity;
                }
                else if (approachCount > 2000)
                {
                    print("Approach is taking too long. Giving up.");
                    vessel.SetWorldVelocity(destination.GetVelocityOfDestination(vessel));
                    mode = CargoMode.Idle;
                }
                else if (destination.GetPreciseDistanceToDestination(vessel).magnitude < safeDistance)
                {
                    print("Approach successful");
                    vessel.SetWorldVelocity(destination.GetVelocityOfDestination(vessel));
                    mode = CargoMode.HoldingPosition;
                }
                else if (approachCount < 100)
                {
                    approachCount++;
                }
                else
                {

                    approachCount++;

                    Vector3 finalVelocity;
                    //print("OriginalVelocity: " + originalVesselVelocity);
                    //print("Current Velocity: " + vessel.obt_velocity);

                    Vector3 reducedVector = new Vector3();
                    Vector3 scalar = new Vector3(1, 1, 1);
                    scalar = scalar / 1;
                    reducedVector = destination.GetPreciseDistanceToDestination(vessel);
                    //print("Reduced Vector - starts at: " + reducedVector);
                    reducedVector.Scale(scalar);
                    //print("Reduced Vector - scales to: " + reducedVector);
                    finalVelocity = originalVesselVelocity + (reducedVector);
                    //print("FinalVelocity: " + finalVelocity);

                    vessel.SetWorldVelocity(finalVelocity);
                }
            }

            if (mode == CargoMode.DriftingTowardsDock)
            {

            }

            if (mode == CargoMode.TeleportRequested)
            {
                mode = CargoMode.TeleportingToSpaceDock;
                teleCount = 0;
                approachCount = 0;
                jumpCount = 0;
            }

            if (mode == CargoMode.TeleportingToSpaceDock)
            {
                if (teleCount < 1)
                {
                    print("Zork: Going onto Rails");
                    Teleport(new Vector3(0, 0, -3000000));
                    print("Zork: Teleporting: count at " + teleCount);

                    //vessel.transform.position = whereToGoFifth;

                    teleCount++;
                }
                else if (teleCount == 1)
                {
                    Vector3 safeVector = destination.GetSafeDistanceToDestination(vessel);
                    print("Zork: translating to " + safeVector);
                    Teleport(safeVector);
                    RotateToDock();
                    teleCount++;
                }
                else
                {
                    print("Teleport finished.");
                    print("normalizing speed with target");
                    MatchSpeedWithDock();
                    mode = CargoMode.AcceleratingTowardsDock;
                }
            }

            if (mode == CargoMode.JumpRequested)
            {
                numberOfJumps++;
                jumpCount = 0;
                mode = CargoMode.Jumping;
                BumpUp();
            }

            if (mode == CargoMode.Jumping)
            {
                jumpCount++;
                if (jumpCount > 15)
                {
                    mode = CargoMode.TeleportRequested;
                }
            }

            base.onPartFixedUpdate();
        }
예제 #26
0
    /// <summary>
    /// Executed by Unity on every first frame <see cref="https://docs.unity3d.com/Manual/ExecutionOrder.html"/>
    /// </summary>
    private void Update()
    {
        Func <Vector3, double> f = v =>
        {
            double result = 0;
            result += 1.0 / (v - new Vector3(0, 0, 0)).sqrMagnitude;
            result += 1.0 / (v - new Vector3(0, Mathf.Sin(Time.time) * 3, Mathf.Cos(Time.time) * 1.5f)).sqrMagnitude;
            result += 1.0 / (v - new Vector3(Mathf.Sin(Time.time) * 3, Mathf.Cos(Time.time) * 1.5f, 0)).sqrMagnitude;
            result += 1.0 / (v - new Vector3(Mathf.Sin(Time.time + Mathf.PI / 2) * 2, 0, Mathf.Cos(Time.time + Mathf.PI / 2) * 2f)).sqrMagnitude;
            // Negative is outside, positive is inside.
            return(result - 2);
        };

        const float MAXC = 4;
        const float MINX = -MAXC, MAXX = MAXC;
        const float MINY = -MAXC, MAXY = MAXC;
        const float MINZ = -MAXC, MAXZ = MAXC;
        const int   STEPS = 28;

        List <Vector3> triangleVertices       = new List <Vector3>();
        List <Vector3> triangleVerticesNormal = new List <Vector3>();
        List <int>     triangles = new List <int>();

        Vector3 cubeSize = new Vector3(
            (MAXX - MINX) / STEPS,
            (MAXY - MINY) / STEPS,
            (MAXZ - MINZ) / STEPS
            );
        const float dd = 0.1f;
        Vector3     dx = new Vector3(dd, 0, 0);
        Vector3     dy = new Vector3(0, dd, 0);
        Vector3     dz = new Vector3(0, 0, dd);

        Vector3 pos0;

        Vector3[] vertices       = new Vector3[_cubeVertices.Count];
        double[]  verticesVal    = new double[_cubeVertices.Count];
        Vector3[] edgesPos       = new Vector3[_cubeEdges.Length];
        Vector3[] edgesPosNormal = new Vector3[_cubeEdges.Length];

        for (int zi = 0; zi < STEPS; zi++)
        {
            for (int yi = 0; yi < STEPS; yi++)
            {
                for (int xi = 0; xi < STEPS; xi++)
                {
                    pos0.x = MINX + xi * (MAXX - MINX) / STEPS;
                    pos0.y = MINY + yi * (MAXX - MINX) / STEPS;
                    pos0.z = MINZ + zi * (MAXX - MINX) / STEPS;

                    int verticesMsk = 0;
                    for (int i = 0; i < _cubeVertices.Count; i++)
                    {
                        vertices[i]    = Vector3.Scale(_cubeVertices[i], cubeSize) + pos0;
                        verticesVal[i] = f(vertices[i]);
                        if (verticesVal[i] > 0) // Positive is inside.
                        {
                            verticesMsk |= 1 << i;
                        }
                    }

                    if (MarchingCubes.Tables.CaseToTrianglesCount[verticesMsk] == 0)
                    {
                        continue;
                    }

                    for (int i = 0; i < _cubeEdges.Length; i++)
                    {
                        Vector3 a = vertices[_cubeEdges[i][0]], b = vertices[_cubeEdges[i][1]];
                        double  av = verticesVal[_cubeEdges[i][0]], bv = verticesVal[_cubeEdges[i][1]];
                        if (av * bv <= 0)
                        {
                            double t = -av / (bv - av);
                            t           = Math.Max(0, Math.Min(1, t));
                            edgesPos[i] = a + (float)t * (b - a);
                            // Negative is outside, positive is inside, so change the sign to point outside.
                            edgesPosNormal[i].x = -(float)(f(edgesPos[i] + dx) - f(edgesPos[i] - dx));
                            edgesPosNormal[i].y = -(float)(f(edgesPos[i] + dy) - f(edgesPos[i] - dy));
                            edgesPosNormal[i].z = -(float)(f(edgesPos[i] + dz) - f(edgesPos[i] - dz));
                            edgesPosNormal[i].Normalize();
                        }
                    }

                    for (int i = 0; i < MarchingCubes.Tables.CaseToTrianglesCount[verticesMsk]; i++)
                    {
                        int3 edgeIds = MarchingCubes.Tables.CaseToVertices[verticesMsk][i];
                        triangleVertices.Add(edgesPos[edgeIds.x]);
                        triangleVertices.Add(edgesPos[edgeIds.y]);
                        triangleVertices.Add(edgesPos[edgeIds.z]);
                        triangleVerticesNormal.Add(edgesPosNormal[edgeIds.x]);
                        triangleVerticesNormal.Add(edgesPosNormal[edgeIds.y]);
                        triangleVerticesNormal.Add(edgesPosNormal[edgeIds.z]);
                        triangles.Add(triangleVertices.Count - 3);
                        triangles.Add(triangleVertices.Count - 2);
                        triangles.Add(triangleVertices.Count - 1);
                    }
                }
            }
        }

        // Here unity automatically assumes that vertices are points and hence will be represented as (x, y, z, 1) in homogenous coordinates
        _mesh.Clear(); // To avoid "the supplied vertex array has less vertices than are referenced by the triangles array" error.
        _mesh.SetVertices(triangleVertices);
        _mesh.SetNormals(triangleVerticesNormal);
        _mesh.SetTriangles(triangles, 0);

        // Upload mesh data to the GPU
        _mesh.UploadMeshData(false);
    }
예제 #27
0
        /// <summary>
        /// Checks for cover along the flight path of the bullet, doesn't check for walls or plants, only intended for cover with partial fillPercent
        /// </summary>
        private bool GetPartialCoverBetween(Vector3 sourceLoc, Vector3 targetLoc, out Thing cover)
        {
            //Sanity check
            if (this.verbProps.projectileDef.projectile.flyOverhead)
            {
                cover = null;
                return false;
            }

            sourceLoc.Scale(new Vector3(1, 0, 1));
            targetLoc.Scale(new Vector3(1, 0, 1));

            //Calculate segment vector and segment amount
            Vector3 shotVec = sourceLoc - targetLoc;    //Vector from target to source
            Vector3 segmentVec = shotVec.normalized * segmentLength;
            float distToCheck = Mathf.Min(distToCheckForCover, shotVec.magnitude);  //The distance to raycast
            float numSegments = distToCheck / segmentLength;

            //Raycast accross all segments to check for cover
            List<IntVec3> checkedCells = new List<IntVec3>();
            Thing targetThing = GridsUtility.GetEdifice(targetLoc.ToIntVec3());
            Thing newCover = null;
            for (int i = 0; i <= numSegments; i++)
            {
                IntVec3 cell = (targetLoc + segmentVec * i).ToIntVec3();
                if (!checkedCells.Contains(cell))
                {
                    //Cover check, if cell has cover compare fillPercent and get the highest piece of cover, ignore if cover is the target (e.g. solar panels, crashed ship, etc)
                    Thing coverAtCell = GridsUtility.GetCover(cell);
                    if (coverAtCell != null
                        && (targetThing == null || !coverAtCell.Equals(targetThing))
                        && (newCover == null || newCover.def.fillPercent < coverAtCell.def.fillPercent))
                    {
                        newCover = coverAtCell;
                    }
                }
            }
            cover = newCover;

            //Report success if found cover that is not a wall or plant
            return (cover != null
                && cover.def.Fillage != FillCategory.Full
                && cover.def.category != ThingCategory.Plant);  //Don't care about trees
        }
    protected void SetupSim()
    {
        // randomly choose scaling before resetting rigid body
        float randomMass = 0;

        BulletSharp.Math.Vector3 randomInertia;
        if (randomScale)
        {
            if (varyScale)
            {
                m_pclScale.x = Random.Range(this.scaleMin, this.scaleMax);
                m_pclScale.y = Random.Range(this.scaleMin, this.scaleMax);
                m_pclScale.z = Random.Range(this.scaleMin, this.scaleMax);
            }
            else
            {
                float uniformScale = Random.Range(this.scaleMin, this.scaleMax);
                m_pclScale.x = uniformScale;
                m_pclScale.y = uniformScale;
                m_pclScale.z = uniformScale;
            }
            //// z can't be more than thrice or less than half of x scale
            //float zmin = Mathf.Max(this.scaleMin, 0.5f * m_pclScale.x);
            //float zmax = Mathf.Min(this.scaleMax, 3.0f * m_pclScale.x);
            //randomScale = Random.Range(zmin, zmax);
            //m_pclScale.z = randomScale;
            //// y can't be greater than 2 times the smallest of x and z
            //float ymax = 2.0f * Mathf.Min(m_pclScale.x, m_pclScale.z);
            //randomScale = Random.Range(this.scaleMin, Mathf.Min(ymax, this.scaleMax));
            //m_pclScale.y = randomScale;

            if (DEBUG)
            {
                Debug.Log("Scaling by " + m_pclScale.ToString());
            }

            // randomMass = m_masses[m_curObjIdx] * m_pclScale.x * m_pclScale.y * m_pclScale.z;
            float randomDensity;
            if (useConstantDensity)
            {
                // density is constant so mass must scale with volume
                randomDensity = densityMin;
                randomMass    = randomDensity * m_masses[m_curObjIdx] * m_pclScale.x * m_pclScale.y * m_pclScale.z;
            }
            else
            {
                randomDensity = Random.Range(densityMin, densityMax);
                randomMass    = randomDensity * m_masses[m_curObjIdx];
            }
            // inertia must scale with volume no matter if the density is constant or not
            BulletSharp.Math.Vector3 objInertiaInfo = m_inertias[m_curObjIdx];
            float scalexyz = m_pclScale.x * m_pclScale.y * m_pclScale.z;
            float scalex2  = m_pclScale.x * m_pclScale.x;
            float scaley2  = m_pclScale.y * m_pclScale.y;
            float scalez2  = m_pclScale.z * m_pclScale.z;
            float inertiax = randomDensity * scalexyz * (scaley2 * objInertiaInfo[1] + scalez2 * objInertiaInfo[2]);
            float inertiay = randomDensity * scalexyz * (scalex2 * objInertiaInfo[0] + scalez2 * objInertiaInfo[2]);
            float inertiaz = randomDensity * scalexyz * (scalex2 * objInertiaInfo[0] + scaley2 * objInertiaInfo[1]);
            randomInertia = new BulletSharp.Math.Vector3(inertiax, inertiay, inertiaz);

            // need to completely destory rigid body because need new mass/moment of inertia
            DestroySimObj();

            DataGenUtils.BulletOBJMesh scaledMesh = m_btmesh.Scale(m_pclScale.x, m_pclScale.y, m_pclScale.z);
            var triVtxarray = new TriangleIndexVertexArray(scaledMesh.indices, scaledMesh.vertices);
            m_cs = new GImpactMeshShape(triVtxarray);
            m_cs.LocalScaling = new BulletSharp.Math.Vector3(1);
            m_cs.Margin       = bodyMargin;
            m_cs.UpdateBound();
            AddCollisionShape(m_cs);

            // move it up so resting on the ground plane
            float miny = float.MaxValue;
            float maxz = float.MinValue;
            float cury;
            float curz;
            for (int i = 0; i < scaledMesh.vertices.Length / 3; i++)
            {
                cury = scaledMesh.vertices[i * 3 + 1];
                if (cury < miny)
                {
                    miny = cury;
                }
                curz = scaledMesh.vertices[i * 3 + 2];
                if (curz > maxz)
                {
                    maxz = curz;
                }
            }
            miny             = -miny;
            m_rbInitTransVec = new BulletSharp.Math.Vector3(0, miny + bodyMargin + m_groundMargin, 0);
            m_rbInitTrans    = Matrix.Translation(m_rbInitTransVec);          //* Matrix.RotationY(Random.Range(0.0f, 360.0f));

            //float gtInertiaX = (1.0f / 12.0f) * randomMass * (3.0f * maxz * maxz + (2.0f * miny) * (2.0f * miny));
            //float gtInertiaZ = gtInertiaX;
            //float gtInertiaY = 0.5f * randomMass * maxz * maxz;
            //BulletSharp.Math.Vector3 gtInertia = new BulletSharp.Math.Vector3(gtInertiaX, gtInertiaY, gtInertiaZ);
            //Debug.Log("GT INERTIA: " + gtInertia.ToString());
            //randomInertia = gtInertia;

            m_rb = CreateRigidBody(randomMass, randomInertia, m_rbInitTrans, m_cs, bodyMat, bodyFriction, viz: RENDER_MODE);
            //m_rb = CreateRigidBody(randomMass, m_rbInitTrans, m_cs, bodyMat, bodyFriction);
            m_rb.AngularFactor = angularFactor;
            m_rb.SetSleepingThresholds(linearSleepThresh, angularSleepThresh);

            m_mass    = randomMass;
            m_inertia = randomInertia;
            m_density = randomDensity;
        }
        else
        {
            // using the same mesh just need to choose a new density
            // steps for determinism
            // https://pybullet.org/Bullet/phpBB3/viewtopic.php?t=3143


            float randomDensity;
            if (useConstantDensity)
            {
                randomDensity = densityMin;
            }
            else
            {
                randomDensity = Random.Range(densityMin, densityMax);
            }
            randomMass = randomDensity * m_masses[m_curObjIdx];
            BulletSharp.Math.Vector3 objInertiaInfo = m_inertias[m_curObjIdx];
            float inertiax = randomDensity * (objInertiaInfo[1] + objInertiaInfo[2]);
            float inertiay = randomDensity * (objInertiaInfo[0] + objInertiaInfo[2]);
            float inertiaz = randomDensity * (objInertiaInfo[0] + objInertiaInfo[1]);
            randomInertia = new BulletSharp.Math.Vector3(inertiax, inertiay, inertiaz);

            m_rb.SetMassProps(randomMass, randomInertia);

            m_rbInitTrans      = Matrix.Translation(m_rbInitTransVec);       // * Matrix.RotationY(Random.Range(0.0f, 360.0f));
            m_rb               = ResetRigidBody(m_rb, randomMass, randomInertia, m_rbInitTrans, m_cs, bodyFriction);
            m_rb.AngularFactor = angularFactor;
            m_rb.SetSleepingThresholds(linearSleepThresh, angularSleepThresh);

            // HingeConstraint hingeConstraint = new HingeConstraint(m_rb, new BulletSharp.Math.Vector3(0.0f), new BulletSharp.Math.Vector3(0.0f, 1.0f, 0.0f), false);
            // m_world.AddConstraint(hingeConstraint);

            // DestroySimObj(); // have to do this to set mass properties but can reuse previously calculated everything else
            // if (m_cs == null) Debug.Log("NOT NULL");
            // m_rb = CreateRigidBody(randomMass, randomInertia, m_rbInitTrans, m_cs, bodyMat, bodyFriction);
            // m_rb.AngularFactor = new BulletSharp.Math.Vector3(angularFactor);
            // m_rb.SetSleepingThresholds(linearSleepThresh, angularSleepThresh);

            m_mass    = randomMass;
            m_inertia = randomInertia;
            m_density = randomDensity;
        }

        m_stepCount = 0;

        m_broadphase.ResetPool(m_colDispatcher);
        m_solver.Reset();

        float curMass = 1.0f / m_rb.InvMass;

        if (DEBUG)
        {
            Debug.Log("Mass: " + curMass.ToString());
        }
        if (DEBUG)
        {
            Debug.Log("LOCAL MOMENT: " + m_rb.LocalInertia.ToString());
        }
        if (DEBUG)
        {
            Debug.Log("COM " + m_rb.CenterOfMassPosition.ToString());
        }
        if (DEBUG)
        {
            Debug.Log("Density " + m_density.ToString());
        }

        // determine impulse position
        ClosestRayResultCallback cb;

        BulletSharp.Math.Vector3 vertexNormal = new BulletSharp.Math.Vector3();
        int missCount = 0;

        do
        {
            // choose random vertex to apply force to
            // pick a random point around in the plane around y position
            float   offsetx   = UnityEngine.Random.Range(-100.0f, 100.0f);
            float   offsetz   = UnityEngine.Random.Range(-100.0f, 100.0f);
            Vector2 offsetvec = new Vector2(offsetx, offsetz);
            // offsetvec.Normalize();
            //float relForceHeight = 0.75f;
            UnityEngine.Vector3 offsetPt = new UnityEngine.Vector3(offsetvec[0],
                                                                   m_rb.CenterOfMassPosition.Y,
                                                                   offsetvec[1]);

            BulletSharp.Math.Vector3 btOffsetPt = BSExtensionMethods2.ToBullet(offsetPt);
            BulletSharp.Math.Vector3 btInnerPt  = m_rb.CenterOfMassPosition;
            cb = new ClosestRayResultCallback(ref btOffsetPt, ref btInnerPt);

            // Debug.DrawLine(BSExtensionMethods2.ToUnity(btInnerPt), offsetPt, Color.red, 2.0f);

            m_world.RayTest(btOffsetPt, btInnerPt, cb);
            if (cb.HasHit)
            {
                m_forcePoint = cb.HitPointWorld;
                vertexNormal = cb.HitNormalWorld;
            }
            else
            {
                missCount++;
                //Debug.Log("ERROR - couldn't find point to apply force to. Retrying...");
                //return;
            }
        } while (!cb.HasHit);

        if (DEBUG)
        {
            Debug.Log("Missed impulse " + missCount.ToString() + " times.");
        }
        if (DEBUG)
        {
            Debug.LogFormat("ForcePoint: " + m_forcePoint.ToString());
        }

        // get force vector
        // loop until force is applied to outside of object
        UnityEngine.Vector3 uForceVec = new UnityEngine.Vector3();

        // initialize force vector to coincide with center of mass
        BulletSharp.Math.Vector3 btForceVec = m_rb.CenterOfMassPosition - m_forcePoint;
        // then randomly vary it within the x/z plane to be within the specified distance
        BulletSharp.Math.Vector3 btVariationVec = new BulletSharp.Math.Vector3(-btForceVec[2], 0.0f, btForceVec[0]);
        btVariationVec.Normalize();
        float varyForce;

        BulletSharp.Math.Vector3 proposedForceVec;
        do
        {
            varyForce        = UnityEngine.Random.Range(-forceDistMax, forceDistMax);
            proposedForceVec = btVariationVec * varyForce + btForceVec;
        } while (proposedForceVec.Dot(vertexNormal) >= 0);         // must also be on the outside of the object
        btForceVec = proposedForceVec;
        btForceVec.Normalize();
        uForceVec = BSExtensionMethods2.ToUnity(btForceVec);
        if (DEBUG)
        {
            Debug.Log("FORCE DIST: " + varyForce.ToString());
        }

        //UnityEngine.Vector3 uVtxNormal = BSExtensionMethods2.ToUnity(vertexNormal);
        //uVtxNormal.Normalize();
        //do
        //{
        //	float forcex = UnityEngine.Random.Range(-1.0f, 1.0f);
        //	float forcez = UnityEngine.Random.Range(-1.0f, 1.0f);
        //	uForceVec.Set(forcex, 0.0f, forcez);
        //	uForceVec.Normalize();
        //} while (UnityEngine.Vector3.Dot(uForceVec, uVtxNormal) >= 0);
        // random constrained magnitude
        float mag = UnityEngine.Random.Range(impulseMin, impulseMax);

        //Debug.Log("Vol: " + objectVolume.ToString());
        // if (varyScale) {
        //  mag *= randomMass; // scale impulse t unity
        //according to object scale
        // } else {
        //  mag *= curMass;
        // }
        mag       *= m_mass;   // scale impulse according to object mass
        uForceVec *= mag;

        // set directly for debugging
        //uForceVec.Set(2.5f, 0.0f, 0.0f);
        //m_forcePoint = new BulletSharp.Math.Vector3(0.0f, m_rb.CenterOfMassPosition.Y, -0.15f);

        m_forceVec = BSExtensionMethods2.ToBullet(uForceVec);

        if (DEBUG)
        {
            Debug.LogFormat("ForceVec: " + m_forceVec.ToString());
        }

        if (DEBUG)
        {
            UnityEngine.Vector3 debugVec = -uForceVec;
            debugVec.Scale(new UnityEngine.Vector3(0.5f, 0.5f, 0.5f));
            Debug.DrawRay(BSExtensionMethods2.ToUnity(m_forcePoint), debugVec, Color.green, 1.0f);
            Debug.DrawLine(BSExtensionMethods2.ToUnity(m_rb.CenterOfMassPosition), BSExtensionMethods2.ToUnity(m_forcePoint), Color.cyan, 1.0f);
            Debug.DrawLine(BSExtensionMethods2.ToUnity(m_rb.CenterOfMassPosition), BSExtensionMethods2.ToUnity(m_rb.CenterOfMassPosition) + BSExtensionMethods2.ToUnity(btVariationVec) * varyForce, Color.blue, 1.0f);
        }

        // apply the random impulse
        BulletSharp.Math.Vector3 radius = m_forcePoint - m_rb.CenterOfMassPosition;
        m_rb.ApplyImpulse(m_forceVec, radius);
        // m_rb.ApplyTorqueImpulse(new BulletSharp.Math.Vector3(0.0f, 1.0f, 0.0f));
        // m_rb.ApplyCentralImpulse(new BulletSharp.Math.Vector3(4.0f, 0.0f, 2.0f));
        // BulletSharp.Math.Vector3 newAngVel = m_rb.AngularVelocity;
        // newAngVel.X = 0.0f;
        // newAngVel.Z = 0.0f;
        // m_rb.AngularVelocity = newAngVel;

        // calculate ground truth for debugging
        //BulletSharp.Math.Vector3 gtAngVel = radius.Cross(m_forceVec) / m_inertia;
        //BulletSharp.Math.Vector3 gtLinVel = m_forceVec / m_mass;
        //Debug.Log("GT LIN VEL: " + gtLinVel.ToString());
        //Debug.Log("GT ANG VEL: " + gtAngVel.ToString());
    }
		public Vector3 getScopeWithScalar(float scalar =1) {
			Vector3 v = new Vector3 (this.Sx, this.Sy, this.Sz);
				v.Scale (new Vector3 (scalar, scalar, scalar));
			return v;
		}
		public Vector3 getTranslationWithScalar(float scalar =1) {
			Vector3 v = new Vector3 (this.Tx, this.Ty, this.Tz);
			v.Scale (new Vector3 (scalar, scalar, scalar));
			return v;
		}
		// set position for bone
		static void SetPosition( Transform[] transforms, NeuronBones bone, Vector3 position, float lerp_ratio )
		{
			Transform t = transforms[(int)bone];
			if( t != null )
			{
				// calculate position when we have scale
				position.Scale( new Vector3( 1.0f / t.parent.lossyScale.x, 1.0f / t.parent.lossyScale.y, 1.0f / t.parent.lossyScale.z ) );
			
				Vector3 pos = Vector3.Lerp( t.localPosition, position, lerp_ratio );
				if( !float.IsNaN( pos.x ) && !float.IsNaN( pos.y ) && !float.IsNaN( pos.z ) )
				{
					t.localPosition = pos;
				}
			}
		}