public idTraceModel Copy() { idTraceModel traceModel = new idTraceModel(); traceModel._type = _type; traceModel._bounds = _bounds; traceModel._offset = _offset; traceModel._edges = (TraceModelEdge[])_edges.Clone(); traceModel._polygons = (TraceModelPolygon[])_polygons.Clone(); traceModel._vertices = (Vector3[])_vertices.Clone(); traceModel._isConvex = _isConvex; return(traceModel); }
public void GetMassProperties(float density, out float mass, out Vector3 centerOfMass, out Matrix inertiaTensor) { inertiaTensor = Matrix.Identity; // if polygon trace model if (_type == TraceModelType.Polygon) { idTraceModel traceModel = VolumeFromPolygon(1.0f); traceModel.GetMassProperties(density, out mass, out centerOfMass, out inertiaTensor); } else { VolumeIntegrals integrals = GetVolumeIntegrals(); // if no volume if (integrals.T0 == 0.0f) { mass = 1.0f; centerOfMass = Vector3.Zero; inertiaTensor = Matrix.Identity; } else { // mass of model mass = density * integrals.T0; // center of mass centerOfMass = integrals.T1 / integrals.T0; // compute inertia tensor inertiaTensor.M11 = density * (integrals.T2.Y + integrals.T2.Z); inertiaTensor.M22 = density * (integrals.T2.Z + integrals.T2.X); inertiaTensor.M33 = density * (integrals.T2.X + integrals.T2.Y); inertiaTensor.M12 = inertiaTensor.M21 = -density * integrals.TP.X; inertiaTensor.M23 = inertiaTensor.M32 = -density * integrals.TP.Y; inertiaTensor.M31 = inertiaTensor.M13 = -density * integrals.TP.Z; // translate inertia tensor to center of mass inertiaTensor.M11 -= mass * (centerOfMass.Y * centerOfMass.Y + centerOfMass.Z * centerOfMass.Z); inertiaTensor.M22 -= mass * (centerOfMass.Z * centerOfMass.Z + centerOfMass.X * centerOfMass.X); inertiaTensor.M33 -= mass * (centerOfMass.X * centerOfMass.X + centerOfMass.Y * centerOfMass.Y); inertiaTensor.M12 = inertiaTensor.M21 += mass * centerOfMass.X * centerOfMass.Y; inertiaTensor.M23 = inertiaTensor.M32 += mass * centerOfMass.Y * centerOfMass.Z; inertiaTensor.M31 = inertiaTensor.M13 += mass * centerOfMass.Z * centerOfMass.X; } } }
private idTraceModel VolumeFromPolygon(float thickness) { idTraceModel traceModel = this.Copy(); traceModel._type = TraceModelType.PolygonVolume; traceModel._vertices = new Vector3[_vertices.Length * 2]; traceModel._edges = new TraceModelEdge[_edges.Length * 3]; traceModel._polygons = new TraceModelPolygon[_edges.Length + 2]; int edgeCount = _edges.Length; int vertCount = _vertices.Length; for (int i = 0; i < edgeCount; i++) { traceModel._vertices[vertCount + i] = _vertices[i] - thickness * _polygons[0].Normal; traceModel._edges[edgeCount + i + 1].V[0] = vertCount + i; traceModel._edges[edgeCount + i + 1].V[1] = vertCount + (i + 1) % vertCount; traceModel._edges[edgeCount * 2 + i + 1].V[0] = i; traceModel._edges[edgeCount * 2 + i + 1].V[1] = vertCount + i; traceModel._polygons[1].Edges[i] = -(edgeCount + i + 1); traceModel._polygons[2 + i].Edges = new int[4]; traceModel._polygons[2 + i].Edges[0] = -(i + 1); traceModel._polygons[2 + i].Edges[1] = edgeCount * 2 + i + 1; traceModel._polygons[2 + i].Edges[2] = edgeCount + i + 1; traceModel._polygons[2 + i].Edges[3] = -(edgeCount * 2 + (i + 1) % edgeCount + 1); traceModel._polygons[2 + i].Normal = Vector3.Cross(_vertices[(i + 1) % vertCount] - _vertices[i], _polygons[0].Normal); traceModel._polygons[2 + i].Normal.Normalize(); traceModel._polygons[2 + i].Distance = (traceModel._polygons[2 + i].Normal * _vertices[i]).Length(); } traceModel._polygons[1].Distance = (traceModel._polygons[1].Normal * traceModel._vertices[edgeCount]).Length(); traceModel.GenerateEdgeNormals(); return(traceModel); }
public bool Equals(idTraceModel traceModel) { if ((this._type != traceModel._type) || (this._vertices.Length != traceModel._vertices.Length) || (this._edges.Length != traceModel._edges.Length) || (this._polygons.Length != traceModel._polygons.Length)) { return(false); } if ((_bounds != traceModel._bounds) || (_offset != traceModel._offset)) { return(false); } switch (_type) { case TraceModelType.Bone: case TraceModelType.Polygon: case TraceModelType.PolygonVolume: case TraceModelType.Custom: int vertexCount = traceModel._vertices.Length; for (int i = 0; i < vertexCount; i++) { if ((i >= _vertices.Length) || (_vertices[i] != traceModel._vertices[i])) { return(false); } } break; } return(true); }
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; }
public bool Equals(idTraceModel traceModel) { if((this._type != traceModel._type) || (this._vertices.Length != traceModel._vertices.Length) || (this._edges.Length != traceModel._edges.Length) || (this._polygons.Length != traceModel._polygons.Length)) { return false; } if((_bounds != traceModel._bounds) || (_offset != traceModel._offset)) { return false; } switch(_type) { case TraceModelType.Bone: case TraceModelType.Polygon: case TraceModelType.PolygonVolume: case TraceModelType.Custom: int vertexCount = traceModel._vertices.Length; for(int i = 0; i < vertexCount; i++) { if((i >= _vertices.Length) || (_vertices[i] != traceModel._vertices[i])) { return false; } } break; } return true; }
public idTraceModel Copy() { idTraceModel traceModel = new idTraceModel(); traceModel._type = _type; traceModel._bounds = _bounds; traceModel._offset = _offset; traceModel._edges = (TraceModelEdge[]) _edges.Clone(); traceModel._polygons = (TraceModelPolygon[]) _polygons.Clone(); traceModel._vertices = (Vector3[]) _vertices.Clone(); traceModel._isConvex = _isConvex; return traceModel; }