示例#1
0
        public void LoadModel(idTraceModel traceModel)
        {
            if (this.Disposed == true)
            {
                throw new ObjectDisposedException("idClipModel");
            }

            _collisionModelHandle = 0;
            _renderModelHandle    = -1;
            _traceModelCache      = GetTraceModelCache(traceModel);

            _bounds = traceModel.Bounds;
        }
示例#2
0
        int Contents(ref idVec3 start, idTraceModel trm, ref idMat3 trmAxis, int contentMask, CmHandle model, ref idVec3 modelOrigin, ref idMat3 modelAxis)
        {
            if (model < 0 || model > this.maxModels || model > MAX_SUBMODELS)
            {
                common.Printf("CollisionModelManager::Contents: invalid model handle\n");
                return(0);
            }
            if (this.models == null || this.models[model] == null)
            {
                common.Printf("CollisionModelManager::Contents: invalid model\n");
                return(0);
            }
            Trace results;

            return(ContentsTrm(out results, start, trm, trmAxis, contentMask, model, modelOrigin, modelAxis));
        }
 public int Contacts(ContactInfo contacts, int maxContacts, ref idVec3 start, ref idVec6 dir, float depth, idTraceModel trm, ref idMat3 trmAxis, int contentMask, CmHandle model, ref idVec3 origin, ref idMat3 modelAxis)
 {
     // same as Translation but instead of storing the first collision we store all collisions as contacts
     this.getContacts = true;
     this.contacts = contacts;
     this.maxContacts = maxContacts;
     this.numContacts = 0;
     idVec3 end = start + dir.SubVec3(0) * depth;
     Trace results;
     Translation(out results, start, end, trm, trmAxis, contentMask, model, origin, modelAxis);
     if (dir.SubVec3(1).LengthSqr() != 0.0f)
     { 
         // FIXME: rotational contacts 
     }
     this.getContacts = false;
     this.maxContacts = 0;
     return this.numContacts;
 }
示例#4
0
        private TraceModelCache GetTraceModelCache(idTraceModel model)
        {
            if (_traceModelCacheDict.ContainsKey(model) == true)
            {
                if (_traceModelCacheDict[model].IsAlive == true)
                {
                    return((TraceModelCache)_traceModelCacheDict[model].Target);
                }

                _traceModelCacheDict.Remove(model);
            }

            TraceModelCache entry = new TraceModelCache();

            entry.TraceModel = model;
            entry.TraceModel.GetMassProperties(1.0f, out entry.Volume, out entry.CenterOfMass, out entry.InertiaTensor);

            WeakReference weakRef = new WeakReference(entry);

            _traceModelCacheDict.Add(model, weakRef);

            return(entry);
        }
 int Contents(ref idVec3 start, idTraceModel trm, ref idMat3 trmAxis, int contentMask, CmHandle model, ref idVec3 modelOrigin, ref idMat3 modelAxis)
 {
     if (model < 0 || model > this.maxModels || model > MAX_SUBMODELS)
     {
         common.Printf("CollisionModelManager::Contents: invalid model handle\n");
         return 0;
     }
     if (this.models == null || this.models[model] == null)
     {
         common.Printf("CollisionModelManager::Contents: invalid model\n");
         return 0;
     }
     Trace results;
     return ContentsTrm(out results, start, trm, trmAxis, contentMask, model, modelOrigin, modelAxis);
 }
        int ContentsTrm(Trace results, ref idVec3 start, idTraceModel trm, ref idMat3 trmAxis, int contentMask, CmHandle model, ref idVec3 modelOrigin, ref idMat3 modelAxis)
        {
            // fast point case
            if (!trm || (trm.bounds[1][0] - trm.bounds[0][0] <= 0.0f &&
                            trm.bounds[1][1] - trm.bounds[0][1] <= 0.0f &&
                            trm.bounds[1][2] - trm.bounds[0][2] <= 0.0f))
            {
                results.c.contents = TransformedPointContents(start, model, modelOrigin, modelAxis);
                results.fraction = (results.c.contents == 0);
                results.endpos = start;
                results.endAxis = trmAxis;
                return results.c.contents;
            }

            this.checkCount++;

            TraceWork tw = new TraceWork();
            tw.trace.fraction = 1.0f;
            tw.trace.c.contents = 0;
            tw.trace.c.type = ContactType.CONTACT_NONE;
            tw.contents = contentMask;
            tw.isConvex = true;
            tw.rotation = false;
            tw.positionTest = true;
            tw.pointTrace = false;
            tw.quickExit = false;
            tw.numContacts = 0;
            tw.model = this.models[(int)model];
            tw.start = start - modelOrigin;
            tw.end = tw.start;

            bool model_rotated = modelAxis.IsRotated();
            if (model_rotated)
                invModelAxis = modelAxis.Transpose();

            // setup trm structure
            SetupTrm(ref tw, trm);

            bool trm_rotated = trmAxis.IsRotated();

            // calculate vertex positions
            if (trm_rotated)
                for (int i = 0; i < tw.numVerts; i++)
                    // rotate trm around the start position
                    tw.vertices[i].p *= trmAxis;
            for (int i = 0; i < tw.numVerts; i++)
                // set trm at start position
                tw.vertices[i].p += tw.start;
            if (model_rotated)
                for (int i = 0; i < tw.numVerts; i++)
                    // rotate trm around model instead of rotating the model
                    tw.vertices[i].p *= invModelAxis;

            // add offset to start point
            if (trm_rotated)
            {
                idVec3 dir = trm->offset * trmAxis;
                tw.start += dir;
                tw.end += dir;
            }
            else
            {
                tw.start += trm->offset;
                tw.end += trm->offset;
            }
            if (model_rotated)
            {
                // rotate trace instead of model
                tw.start *= invModelAxis;
                tw.end *= invModelAxis;
            }

            // setup trm vertices
            tw.size.Clear();
            for (int i = 0; i < tw.numVerts; i++)
                // get axial trm size after rotations
                tw.size.AddPoint(tw.vertices[i].p - tw.start);

            // setup trm edges
            for (int i = 1; i <= tw.numEdges; i++)
            {
                // edge start, end and pluecker coordinate
                tw.edges[i].start = tw.vertices[tw.edges[i].vertexNum[0]].p;
                tw.edges[i].end = tw.vertices[tw.edges[i].vertexNum[1]].p;
                tw.edges[i].pl.FromLine(tw.edges[i].start, tw.edges[i].end);
            }

            // setup trm polygons
            if (trm_rotated & model_rotated)
            {
                idMat3 tmpAxis = trmAxis * invModelAxis;
                for (int i = 0; i < tw.numPolys; i++)
                    tw.polys[i].plane *= tmpAxis;
            }
            else if (trm_rotated)
            {
                for (int i = 0; i < tw.numPolys; i++)
                    tw.polys[i].plane *= trmAxis;
            }
            else if (model_rotated)
            {
                for (int i = 0; i < tw.numPolys; i++)
                    tw.polys[i].plane *= invModelAxis;
            }
            for (int i = 0; i < tw.numPolys; i++)
                tw.polys[i].plane.FitThroughPoint(tw.edges[abs(tw.polys[i].edges[0])].start);

            // bounds for full trace, a little bit larger for epsilons
            for (int i = 0; i < 3; i++)
            {
                if (tw.start[i] < tw.end[i])
                {
                    tw.bounds[0][i] = tw.start[i] + tw.size[0][i] - CM_BOX_EPSILON;
                    tw.bounds[1][i] = tw.end[i] + tw.size[1][i] + CM_BOX_EPSILON;
                }
                else
                {
                    tw.bounds[0][i] = tw.end[i] + tw.size[0][i] - CM_BOX_EPSILON;
                    tw.bounds[1][i] = tw.start[i] + tw.size[1][i] + CM_BOX_EPSILON;
                }
                if (idMath.Fabs(tw.size[0][i]) > idMath.Fabs(tw.size[1][i]))
                    tw.extents[i] = idMath.Fabs(tw.size[0][i]) + CM_BOX_EPSILON;
                else
                    tw.extents[i] = idMath.Fabs(tw.size[1][i]) + CM_BOX_EPSILON;
            }

            // trace through the model
            TraceThroughModel(ref tw);

            results = tw.trace;
            results.fraction = (results.c.contents == 0);
            results.endpos = start;
            results.endAxis = trmAxis;
            return results.c.contents;
        }
示例#7
0
        int ContentsTrm(Trace results, ref idVec3 start, idTraceModel trm, ref idMat3 trmAxis, int contentMask, CmHandle model, ref idVec3 modelOrigin, ref idMat3 modelAxis)
        {
            // fast point case
            if (!trm || (trm.bounds[1][0] - trm.bounds[0][0] <= 0.0f &&
                         trm.bounds[1][1] - trm.bounds[0][1] <= 0.0f &&
                         trm.bounds[1][2] - trm.bounds[0][2] <= 0.0f))
            {
                results.c.contents = TransformedPointContents(start, model, modelOrigin, modelAxis);
                results.fraction   = (results.c.contents == 0);
                results.endpos     = start;
                results.endAxis    = trmAxis;
                return(results.c.contents);
            }

            this.checkCount++;

            TraceWork tw = new TraceWork();

            tw.trace.fraction   = 1.0f;
            tw.trace.c.contents = 0;
            tw.trace.c.type     = ContactType.CONTACT_NONE;
            tw.contents         = contentMask;
            tw.isConvex         = true;
            tw.rotation         = false;
            tw.positionTest     = true;
            tw.pointTrace       = false;
            tw.quickExit        = false;
            tw.numContacts      = 0;
            tw.model            = this.models[(int)model];
            tw.start            = start - modelOrigin;
            tw.end = tw.start;

            bool model_rotated = modelAxis.IsRotated();

            if (model_rotated)
            {
                invModelAxis = modelAxis.Transpose();
            }

            // setup trm structure
            SetupTrm(ref tw, trm);

            bool trm_rotated = trmAxis.IsRotated();

            // calculate vertex positions
            if (trm_rotated)
            {
                for (int i = 0; i < tw.numVerts; i++)
                {
                    // rotate trm around the start position
                    tw.vertices[i].p *= trmAxis;
                }
            }
            for (int i = 0; i < tw.numVerts; i++)
            {
                // set trm at start position
                tw.vertices[i].p += tw.start;
            }
            if (model_rotated)
            {
                for (int i = 0; i < tw.numVerts; i++)
                {
                    // rotate trm around model instead of rotating the model
                    tw.vertices[i].p *= invModelAxis;
                }
            }

            // add offset to start point
            if (trm_rotated)
            {
                idVec3 dir = trm->offset * trmAxis;
                tw.start += dir;
                tw.end   += dir;
            }
            else
            {
                tw.start += trm->offset;
                tw.end   += trm->offset;
            }
            if (model_rotated)
            {
                // rotate trace instead of model
                tw.start *= invModelAxis;
                tw.end   *= invModelAxis;
            }

            // setup trm vertices
            tw.size.Clear();
            for (int i = 0; i < tw.numVerts; i++)
            {
                // get axial trm size after rotations
                tw.size.AddPoint(tw.vertices[i].p - tw.start);
            }

            // setup trm edges
            for (int i = 1; i <= tw.numEdges; i++)
            {
                // edge start, end and pluecker coordinate
                tw.edges[i].start = tw.vertices[tw.edges[i].vertexNum[0]].p;
                tw.edges[i].end   = tw.vertices[tw.edges[i].vertexNum[1]].p;
                tw.edges[i].pl.FromLine(tw.edges[i].start, tw.edges[i].end);
            }

            // setup trm polygons
            if (trm_rotated & model_rotated)
            {
                idMat3 tmpAxis = trmAxis * invModelAxis;
                for (int i = 0; i < tw.numPolys; i++)
                {
                    tw.polys[i].plane *= tmpAxis;
                }
            }
            else if (trm_rotated)
            {
                for (int i = 0; i < tw.numPolys; i++)
                {
                    tw.polys[i].plane *= trmAxis;
                }
            }
            else if (model_rotated)
            {
                for (int i = 0; i < tw.numPolys; i++)
                {
                    tw.polys[i].plane *= invModelAxis;
                }
            }
            for (int i = 0; i < tw.numPolys; i++)
            {
                tw.polys[i].plane.FitThroughPoint(tw.edges[abs(tw.polys[i].edges[0])].start);
            }

            // bounds for full trace, a little bit larger for epsilons
            for (int i = 0; i < 3; i++)
            {
                if (tw.start[i] < tw.end[i])
                {
                    tw.bounds[0][i] = tw.start[i] + tw.size[0][i] - CM_BOX_EPSILON;
                    tw.bounds[1][i] = tw.end[i] + tw.size[1][i] + CM_BOX_EPSILON;
                }
                else
                {
                    tw.bounds[0][i] = tw.end[i] + tw.size[0][i] - CM_BOX_EPSILON;
                    tw.bounds[1][i] = tw.start[i] + tw.size[1][i] + CM_BOX_EPSILON;
                }
                if (idMath.Fabs(tw.size[0][i]) > idMath.Fabs(tw.size[1][i]))
                {
                    tw.extents[i] = idMath.Fabs(tw.size[0][i]) + CM_BOX_EPSILON;
                }
                else
                {
                    tw.extents[i] = idMath.Fabs(tw.size[1][i]) + CM_BOX_EPSILON;
                }
            }

            // trace through the model
            TraceThroughModel(ref tw);

            results          = tw.trace;
            results.fraction = (results.c.contents == 0);
            results.endpos   = start;
            results.endAxis  = trmAxis;
            return(results.c.contents);
        }
示例#8
0
        private void InitDefaultPhysics(Vector3 origin, Matrix axis)
        {
            string      temp      = _spawnArgs.GetString("clipmodel", "");
            idClipModel clipModel = null;

            // check if a clipmodel key/value pair is set
            if (temp != string.Empty)
            {
                if (idClipModel.CheckModel(temp) != null)
                {
                    clipModel = new idClipModel(temp);
                }
            }

            if (_spawnArgs.GetBool("noclipmodel", false) == false)
            {
                // check if mins/maxs or size key/value pairs are set
                if (clipModel == null)
                {
                    idBounds bounds       = idBounds.Zero;
                    bool     setClipModel = false;

                    if ((_spawnArgs.ContainsKey("mins") == true) &&
                        (_spawnArgs.ContainsKey("maxs") == true))
                    {
                        bounds       = new idBounds(_spawnArgs.GetVector3("mins"), _spawnArgs.GetVector3("maxs"));
                        setClipModel = true;

                        if ((bounds.Min.X > bounds.Max.X) ||
                            (bounds.Min.Y > bounds.Max.Y) ||
                            (bounds.Min.Z > bounds.Max.Z))
                        {
                            idConsole.Error("Invalid bounds '{0}'-'{1}' on entity '{2}'", bounds.Min, bounds.Max, this.Name);
                        }
                    }
                    else if (_spawnArgs.ContainsKey("size") == true)
                    {
                        Vector3 size = _spawnArgs.GetVector3("size");

                        if ((size.X < 0.0f) ||
                            (size.Y < 0.0f) ||
                            (size.Z < 0.0f))
                        {
                            idConsole.Error("Invalid size '{0}' on entity '{1}'", size, this.Name);
                        }

                        setClipModel = true;
                        bounds       = new idBounds(
                            new Vector3(size.X * -0.5f, size.Y * -0.5f, 0.0f),
                            new Vector3(size.X * 0.5f, size.Y * 0.5f, size.Z)
                            );
                    }

                    if (setClipModel == true)
                    {
                        int sideCount = _spawnArgs.GetInteger("cyclinder", 0);

                        idTraceModel traceModel = new idTraceModel();

                        if (sideCount > 0)
                        {
                            idConsole.Warning("TODO: traceModel.SetupCyclinder(bounds, (sideCount < 3) ? 3 : sideCount);");
                        }
                        else if ((sideCount = _spawnArgs.GetInteger("cone", 0)) > 0)
                        {
                            idConsole.Warning("TODO: traceModel.SetupCone(bounds, (sideCount < 3) ? 3 : sideCount);");
                        }
                        else
                        {
                            traceModel.SetupBox(bounds);
                        }

                        clipModel = new idClipModel(traceModel);
                    }
                }

                // check if the visual model can be used as collision model
                if (clipModel == null)
                {
                    temp = _spawnArgs.GetString("model");

                    if (temp != string.Empty)
                    {
                        if (idClipModel.CheckModel(temp) != null)
                        {
                            clipModel = new idClipModel(temp);
                        }
                    }
                }
            }

            _defaultPhysicsObject.Self = this;
            _defaultPhysicsObject.SetClipModel(clipModel, 1.0f);
            _defaultPhysicsObject.SetOrigin(origin);
            _defaultPhysicsObject.SetAxis(axis);

            _physics = _defaultPhysicsObject;
        }
示例#9
0
		public void LoadModel(idTraceModel traceModel)
		{
			if(this.Disposed == true)
			{
				throw new ObjectDisposedException("idClipModel");
			}

			_collisionModelHandle = 0;
			_renderModelHandle = -1;			
			_traceModelCache = GetTraceModelCache(traceModel);

			_bounds = traceModel.Bounds;
		}
示例#10
0
		private TraceModelCache GetTraceModelCache(idTraceModel model)
		{
			if(_traceModelCacheDict.ContainsKey(model) == true)
			{
				if(_traceModelCacheDict[model].IsAlive == true)
				{
					return (TraceModelCache) _traceModelCacheDict[model].Target;
				}

				_traceModelCacheDict.Remove(model);
			}

			TraceModelCache entry = new TraceModelCache();
			entry.TraceModel = model;
			entry.TraceModel.GetMassProperties(1.0f, out entry.Volume, out entry.CenterOfMass, out entry.InertiaTensor);

			WeakReference weakRef = new WeakReference(entry);
			_traceModelCacheDict.Add(model, weakRef);

			return entry;
		}
示例#11
0
		public idClipModel(idTraceModel traceModel) 
		{
			Init();
			LoadModel(traceModel);
		}
        public int Contacts(ContactInfo contacts, int maxContacts, ref idVec3 start, ref idVec6 dir, float depth, idTraceModel trm, ref idMat3 trmAxis, int contentMask, CmHandle model, ref idVec3 origin, ref idMat3 modelAxis)
        {
            // same as Translation but instead of storing the first collision we store all collisions as contacts
            this.getContacts = true;
            this.contacts    = contacts;
            this.maxContacts = maxContacts;
            this.numContacts = 0;
            idVec3 end = start + dir.SubVec3(0) * depth;
            Trace  results;

            Translation(out results, start, end, trm, trmAxis, contentMask, model, origin, modelAxis);
            if (dir.SubVec3(1).LengthSqr() != 0.0f)
            {
                // FIXME: rotational contacts
            }
            this.getContacts = false;
            this.maxContacts = 0;
            return(this.numContacts);
        }
示例#13
0
 public idClipModel(idTraceModel traceModel)
 {
     Init();
     LoadModel(traceModel);
 }