Esempio n. 1
0
        private CrushData GetClosestCrushData(Vector3 contactPoint)
        {
            float     minDist = 9999;
            CrushData minData = null;

            foreach (CrushData data in _carFile.CrushSections[1].Data)
            {
                Vector3 crushPoint = Vector3.Transform(_localVertices[data.RefVertex].Position, GameVars.ScaleMatrix * _actor.GlobalPose);
                float   dist       = Vector3.Distance(crushPoint, contactPoint);
                if (dist < minDist)
                {
                    minDist = dist;
                    minData = data;
                }
            }

            return(minData);
        }
Esempio n. 2
0
        public void OnContact(Vector3 contactPoint, float force2, Vector3 normal)
        {
            List <int> hitPoints = new List <int>();

            Vector3 force = force2 * normal;

            force = Vector3.Transform(force, _actor.GlobalOrientation);

            force.X *= 0.5f;  //limit sideways crush
            force.Y *= 0.9f;

            force *= 0.00000011f * _carFile.CrushSections[1].DamageMultiplier; //scale it down to a managable number
            float forceSize = force.Length();

            //if (forceSize > 0.04f)
            //{
            //force *= 0.04f / forceSize; //cap max force so things dont get loco
            //}

            if (forceSize < 0.004f)
            {
                return;
            }

            Vector3 force3 = force;

            force.X = Math.Abs(force.X);
            force.Y = Math.Abs(force.Y);
            force.Z = Math.Abs(force.Z);


            if (float.IsNaN(Vector3.Normalize(force).X))
            {
                return;
            }

            int hitpoints = 0;

            CrushData data = GetClosestCrushData(contactPoint);

            if (data == null)
            {
                return; //no crush data for this car
            }
            //foreach (CrushData data in _carFile.CrushSections[1].Data)
            {
                Vector3 crushPoint = Vector3.Transform(_localVertices[data.RefVertex].Position, GameVars.ScaleMatrix * _actor.GlobalPose);

                // if (Vector3.Distance(crushPoint, contactPoint) < 0.5f)
                {
                    hitPoints.Add(data.RefVertex);
                    hitpoints++;
                    Vector3 curPos = _localVertices[data.RefVertex].Position;

                    Vector3 directedForce = new Vector3();
                    directedForce.X = curPos.X < 0 ? force.X : -force.X;
                    directedForce.Y = curPos.Y < 0 ? force.Y : -force.Y;
                    directedForce.Z = curPos.Z < 0 ? force.Z : -force.Z;

                    Vector3 parentScale = new Vector3();
                    parentScale.X  = directedForce.X > 0 ? data.LeftScale : data.RightScale;
                    parentScale.Y  = directedForce.Y > 0 ? data.BottomScale : data.TopScale;
                    parentScale.Z  = directedForce.Z > 0 ? data.FrontScale : data.RearScale;
                    directedForce *= parentScale;


                    Vector3 oldPos = _localVertices[data.RefVertex].Position;
                    curPos = KeepCrushPositionInBounds(curPos + directedForce, data.Box);
                    float distanceMoved = Vector3.Distance(oldPos, curPos);
                    _localVertices[data.RefVertex].Position = curPos;

                    Vector3 parentDir = curPos - oldPos;

                    if (distanceMoved < 0.0002f)
                    {
                        return;
                    }

                    Vector3 normalforce = Vector3.Normalize(force);

                    foreach (CrushPoint point in data.Points)
                    {
                        if (point.VertexIndex < 0)
                        {
                            continue;
                        }

                        if (float.IsNaN(normalforce.X) || float.IsNaN(normalforce.Y) || float.IsNaN(normalforce.Z))
                        {
                            break;
                        }

                        curPos = _localVertices[point.VertexIndex].Position;

                        //float distanceFromParent = Vector3.Distance(curPos, _localVertices[data.RefVertex].Position);
                        //float originalDistanceFromParent = Vector3.Distance(curPos, _originalPositions[data.RefVertex]);

                        //if (distanceFromParent < originalDistanceFromParent)
                        //    return;

                        //directedForce = force * parentScale;

                        Vector3 vdir = _localVertices[data.RefVertex].Position - _localVertices[point.VertexIndex].Position;
                        vdir.Normalize();

                        Vector3 newpos = _localVertices[point.VertexIndex].Position + (vdir * distanceMoved * parentScale * 2f * (1 - point.DistanceFromParent));
                        if (point.DistanceFromParent < 0.1f || Engine.Random.Next(10) % 2 == 0)
                        {
                            newpos = _localVertices[point.VertexIndex].Position + (parentDir * 0.6f * (1 - point.DistanceFromParent));
                        }
                        //else
                        //{
                        //}

                        float dist3 = Vector3.Distance(_originalPositions[point.VertexIndex], newpos);
                        // if were not too far away from orig position and this will move us closer to our parent, move this vert
                        if (dist3 < 0.07f)
                        {
                            _localVertices[point.VertexIndex].Position = newpos;
                            if (_vertexLinks[point.VertexIndex] != null)
                            {
                                foreach (int idx in _vertexLinks[point.VertexIndex])
                                {
                                    _localVertices[idx].Position = newpos;
                                }
                            }
                        }
                        else
                        {
                            //GameConsole.WriteEvent("not moving child");
                        }


                        //force = normalforce * distanceMoved * MathHelper.Lerp(1f, 0.1f, point.DistanceFromParent);

                        //curPos = _localVertices[point.VertexIndex].Position;
                        //if (Math.Abs(force.Y) < 0.0001f)
                        //    force.Y *= (_localVertices[data.RefVertex].Position.Y - curPos.Y) * 1000;
                        //directedForce.X = curPos.X < 0 ? force.X : -force.X;
                        //directedForce.Y = curPos.Y < 0 ? force.Y : -force.Y;
                        //directedForce.Z = curPos.Z < 0 ? force.Z : -force.Z;
                        ////rnd.Y = (_localVertices[data.RefVertex].Position.Y - curPos.Y) * 80;
                        //rnd.Y *= curPos.Y > 0 ? 1 : -1;

                        ////Vector3 forceToUse = directedForce * Vector3.Lerp(Vector3.One, rnd * 1.5f, point.DistanceFromParent); //as we get further away from parent, more random
                        //if (Vector3.Distance(_originalPositions[point.VertexIndex], curPos + directedForce) < 0.04f)
                        //    _localVertices[point.VertexIndex].Position = curPos + directedForce;
                    }
                    _changed = true;
                }
            }

            if (_changed)
            {
                bool tidied = false;
                foreach (CrushData data2 in _carFile.CrushSections[1].Data)
                {
                    Vector3 oldpos = _localVertices[data2.RefVertex].Position;
                    _localVertices[data2.RefVertex].Position = KeepCrushPositionInBounds(_localVertices[data2.RefVertex].Position, data2.Box);
                    if (oldpos != _localVertices[data2.RefVertex].Position)
                    {
                        tidied = true;
                    }
                }

                if (tidied)
                {
                    GameConsole.WriteEvent("tidied up");
                }

                for (int i = 0; i < _localVertices.Length; i++)
                {
                    if (float.IsNaN(_localVertices[i].Position.X) || float.IsNaN(_localVertices[i].Position.Y) || float.IsNaN(_localVertices[i].Position.Z))
                    {
                    }
                }
            }

            if (hitpoints > 0)
            {
                GameConsole.WriteEvent("f: " + Math.Round(forceSize, 4) + ", pts: " + hitpoints);
                _lastHitPts = hitPoints;
            }
        }