// Lazy-loading and then returning reference to model // Doesn't load vertex/index shader and doesn't touch GPU. Use it when you need model data - vertex, triangles, octre... public static MyModel GetModelOnlyData(string modelAsset) { if (string.IsNullOrEmpty(modelAsset)) return null; MyModel model; if (!m_models.TryGetValue(modelAsset, out model)) { model = new MyModel(modelAsset); m_models[modelAsset] = model; } model.LoadData(); return model; }
// Use this constructor to build the octree public MyModelOctree(MyModel model) { // we can't use performance timer, because octree now loaded in parallel tasks //MyPerformanceTimer.OctreeBuilding.Start(); m_model = model; // Bounding box for the root node - get it from model (we need to trust the model that it will be good) m_rootNode = new MyModelOctreeNode(model.BoundingBox); // Add model triangles into octree for (int i = 0; i < m_model.Triangles.Length; i++) { // Add triangleVertexes to octree m_rootNode.AddTriangle(model, i, 0); } // This method will look if node has all its childs null, and if yes, destroy childs array (saving memory + making traversal faster, because we don't need to traverse whole array) m_rootNode.OptimizeChilds(); // we can't use performance timer, because octree now loaded in parallel tasks //MyPerformanceTimer.OctreeBuilding.End(); }
// Finds intersection between line and model, using octree for speedup the lookup. // Another speedup is, that first we check triangles that are directly in the node and then start // checking node's childs. But only if child node instersection is less than last know min distance. MyIntersectionResultLineTriangle? GetIntersectionWithLineRecursive(MyModel model, ref LineD line, double? minDistanceUntilNow) { // Check if line intersects bounding box of this node and if distance to bounding box is less then last know min distance Line lineF = (Line)line; double? distanceToBoundingBox = MyUtils.GetLineBoundingBoxIntersection(ref lineF, ref m_boundingBox); if ((distanceToBoundingBox.HasValue == false) || ((minDistanceUntilNow != null) && (minDistanceUntilNow < distanceToBoundingBox.Value))) return null; // Triangles that are directly in this node MyIntersectionResultLineTriangle? foundIntersection = null; // temporary variable for storing tirngle boundingbox info BoundingBox triangleBoundingBox = new BoundingBox(); BoundingBox lineBB = BoundingBox.CreateInvalid(); lineBB = lineBB.Include(line.From); lineBB = lineBB.Include(line.To); for (int i = 0; i < m_triangleIndices.Count; i++) { int triangleIndex = m_triangleIndices[i]; model.GetTriangleBoundingBox(triangleIndex, ref triangleBoundingBox); // First test intersection of triangleVertexes's bounding box with line's bounding box. And only if they overlap or intersect, do further intersection tests. if (triangleBoundingBox.Intersects(ref lineBB)) { // See that we swaped vertex indices!! MyTriangle_Vertexes triangle; MyTriangleVertexIndices triangleIndices = model.Triangles[triangleIndex]; triangle.Vertex0 = model.GetVertex(triangleIndices.I0); triangle.Vertex1 = model.GetVertex(triangleIndices.I2); triangle.Vertex2 = model.GetVertex(triangleIndices.I1); double? distance = MyUtils.GetLineTriangleIntersection(ref lineF, ref triangle); // If intersection occured and if distance to intersection is closer to origin than any previous intersection if ((distance != null) && ((foundIntersection == null) || (distance.Value < foundIntersection.Value.Distance))) { Vector3 calculatedTriangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangle); // We need to remember original triangleVertexes coordinates (not transformed by world matrix) foundIntersection = new MyIntersectionResultLineTriangle(ref triangle, ref calculatedTriangleNormal, distance.Value); } } } // Get intersection with childs of this node if (m_childs != null) { for (int i = 0; i < m_childs.Count; i++) { MyIntersectionResultLineTriangle? childIntersection = m_childs[i].GetIntersectionWithLineRecursive(model, ref line, (foundIntersection == null) ? (double?)null : foundIntersection.Value.Distance); // If intersection occured and if distance to intersection is closer to origin than any previous intersection foundIntersection = MyIntersectionResultLineTriangle.GetCloserIntersection(ref foundIntersection, ref childIntersection); } } return foundIntersection; }
protected void DebugDrawDummies(MyModel model) { if (model == null) { return; } foreach (var dummy in model.Dummies) { MyModelDummy modelDummy = dummy.Value; MatrixD worldMatrix = (MatrixD)modelDummy.Matrix * m_entity.PositionComp.WorldMatrix; VRageRender.MyRenderProxy.DebugDrawText3D(worldMatrix.Translation, dummy.Key, Color.White, 0.7f, false); VRageRender.MyRenderProxy.DebugDrawAxis(MatrixD.Normalize(worldMatrix), 0.1f, false); VRageRender.MyRenderProxy.DebugDrawOBB(worldMatrix, Vector3.One, 1, false, false); } }
// Lazy-loading and then returning reference to model // Doesn't load vertex/index shader and doesn't touch GPU. Use it when you need model data - vertex, triangles, octre... public static MyModel GetModelOnlyDummies(string modelAsset) { MyModel model; if (!m_models.TryGetValue(modelAsset, out model)) { model = new MyModel(modelAsset); m_models[modelAsset] = model; } model.LoadOnlyDummies(); return model; }
void CreateBreakableShapeFromCollisionShapes(MyModel model, Vector3 defaultSize, MyPhysicalModelDefinition modelDef) { // Make box half edge length of the grid so fractured block is smaller than not fractured, also good for compounds HkShape shape; if (model.HavokCollisionShapes != null && model.HavokCollisionShapes.Length > 0) { if (model.HavokCollisionShapes.Length > 1) { shape = HkListShape.Create(model.HavokCollisionShapes, model.HavokCollisionShapes.Length, HkReferencePolicy.None); } else { shape = model.HavokCollisionShapes[0]; shape.AddReference(); } } else { //modelDef.Size * (modelDef.CubeSize == MyCubeSize.Large ? 2.5f : 0.25f) shape = new HkBoxShape(defaultSize * 0.5f, MyPerGameSettings.PhysicsConvexRadius); } var boxBreakable = new HkdBreakableShape(shape); boxBreakable.Name = model.AssetName; boxBreakable.SetMass(modelDef.Mass); model.HavokBreakableShapes = new HkdBreakableShape[] { boxBreakable }; shape.RemoveReference(); }
public void RefreshModels(string model, string modelCollision) { if (model != null) { Render.ModelStorage = MyModels.GetModelOnlyData(model); PositionComp.LocalVolumeOffset = Render.GetModel().BoundingSphere.Center; } if (modelCollision != null) m_modelCollision = MyModels.GetModelOnlyData(modelCollision); if (Render.ModelStorage != null) { this.PositionComp.LocalAABB = Render.GetModel().BoundingBox; bool idAllocationState = MyEntityIdentifier.AllocationSuspended; try { MyEntityIdentifier.AllocationSuspended = false; if (Subparts == null) Subparts = new Dictionary<string, MyEntitySubpart>(); else { foreach (var existingSubpart in Subparts) { Hierarchy.RemoveChild(existingSubpart.Value); existingSubpart.Value.Close(); } Subparts.Clear(); } MyEntitySubpart.Data data = new MyEntitySubpart.Data(); foreach (var dummy in Render.GetModel().Dummies) { // Check of mirrored matrix of dummy object is under fake, because characters have mirrored dummies if (MyFakes.ENABLE_DUMMY_MIRROR_MATRIX_CHECK) { // This should not be here but if you want to check bad matrices of other types if (!(this is MyCharacter)) { Debug.Assert(!dummy.Value.Matrix.IsMirrored()); } } if (!MyEntitySubpart.GetSubpartFromDummy(model, dummy.Key, dummy.Value, ref data)) continue; MyEntitySubpart subpart = new MyEntitySubpart(); subpart.Render.EnableColorMaskHsv = Render.EnableColorMaskHsv; subpart.Render.ColorMaskHsv = Render.ColorMaskHsv; subpart.Init(null, data.File, this, null); subpart.PositionComp.LocalMatrix = data.InitialTransform; Subparts[data.Name] = subpart; if (InScene) subpart.OnAddedToScene(this); } } finally { MyEntityIdentifier.AllocationSuspended = idAllocationState; } if (Render.GetModel().GlassData != null) { Render.NeedsDraw = true; Render.NeedsDrawFromParent = true; } } else { //entities without model has box with side length = 1 by default float defaultBoxHalfSize = 0.5f; this.PositionComp.LocalAABB = new BoundingBox(new Vector3(-defaultBoxHalfSize), new Vector3(defaultBoxHalfSize)); } }
// Add triangleVertexes into this node or its child or child's child... public void AddTriangle(MyModel model, int triangleIndex, int recursiveLevel) { BoundingBox triangleBoundingBox = new BoundingBox(); model.GetTriangleBoundingBox(triangleIndex, ref triangleBoundingBox); if (recursiveLevel != MAX_RECURSIVE_LEVEL) { // If we didn't reach max recursive level, we look for child where triangleVertexes can be completely contained for (int i = 0; i < OCTREE_CHILDS_COUNT; i++) { BoundingBox childBoundingBox = GetChildBoundingBox(m_boundingBox, i); // If child completely contains the triangleVertexes, we add it to this child (or its child...child). if (childBoundingBox.Contains(triangleBoundingBox) == ContainmentType.Contains) { if (m_childs[i] == null) m_childs[i] = new MyModelOctreeNode(childBoundingBox); m_childs[i].AddTriangle(model, triangleIndex, recursiveLevel + 1); // Child completely contains triangle, so also current bounding box must contain that triangle m_realBoundingBox = m_realBoundingBox.Include(ref triangleBoundingBox.Min); m_realBoundingBox = m_realBoundingBox.Include(ref triangleBoundingBox.Max); return; } } } // If we get here, it was because we reached max recursive level or no child completely contained the triangleVertexes, so we add triangleVertexes to this node m_triangleIndices.Add(triangleIndex); m_realBoundingBox = m_realBoundingBox.Include(ref triangleBoundingBox.Min); m_realBoundingBox = m_realBoundingBox.Include(ref triangleBoundingBox.Max); }
// Don't call remove reference on this, this shape is pooled public HkShape GetDebrisShape(MyModel model, HkShapeType shapeType) { MyModelShapeInfo info = new MyModelShapeInfo(); info.Model = model; info.ShapeType = shapeType; HkShape shape; if (!m_shapes.TryGetValue(info, out shape)) { shape = CreateShape(model, shapeType); m_shapes.Add(info, shape); } return shape; }
HkShape CreateShape(MyModel model, HkShapeType shapeType) { switch(shapeType) { case HkShapeType.Box: Vector3 halfExtents = (model.BoundingBox.Max - model.BoundingBox.Min) / 2; return new HkBoxShape(Vector3.Max(halfExtents - 0.1f, new Vector3(0.05f)), 0.02f); break; case HkShapeType.Sphere: return new HkSphereShape(model.BoundingSphere.Radius); break; case HkShapeType.ConvexVertices: m_tmpVerts.Clear(); for (int i = 0; i < model.GetVerticesCount(); i++) { m_tmpVerts.Add(model.GetVertex(i)); } return new HkConvexVerticesShape(m_tmpVerts.GetInternalArray(), m_tmpVerts.Count, true, 0.1f); break; } throw new InvalidOperationException("This shape is not supported"); }
public override void RecreateControls(bool constructor) { base.RecreateControls(constructor); m_currentPosition = -m_size.Value / 2.0f + new Vector2(0.02f, 0.10f); m_currentPosition.Y += 0.01f; m_scale = 0.7f; AddCaption("Render Model FX", Color.Yellow.ToVector4()); AddShareFocusHint(); //if (MySession.ControlledObject == null) //return; AddButton(new StringBuilder("Reload textures"), delegate { VRageRender.MyRenderProxy.ReloadTextures(); }); //Line line = new Line(MySector.MainCamera.Position, MySector.MainCamera.Position + MySector.MainCamera.ForwardVector * 10); //var res = MyEntities.GetIntersectionWithLine(ref line, null, null); //if (!res.HasValue) // return; ////MyModel model = MySession.ControlledObject.ModelLod0; //m_model = res.Value.Entity.ModelLod0; m_modelsCombo = AddCombo(); var modelList = MyModels.LoadedModels.Values.ToList(); if (modelList.Count == 0) return; for (int i = 0; i < modelList.Count; i++) { var model = modelList[i]; m_modelsCombo.AddItem((int)i, new StringBuilder(System.IO.Path.GetFileNameWithoutExtension(model.AssetName))); } m_modelsCombo.SelectItemByIndex(m_currentModelSelectedItem); m_modelsCombo.ItemSelected += new MyGuiControlCombobox.ItemSelectedDelegate(modelsCombo_OnSelect); m_model = modelList[m_currentModelSelectedItem]; if (m_model == null) return; m_meshesCombo = AddCombo(); for (int i = 0; i < m_model.GetMeshList().Count; i++) { var mesh = m_model.GetMeshList()[i]; m_meshesCombo.AddItem((int)i, new StringBuilder(mesh.Material.Name)); } m_meshesCombo.SelectItemByIndex(m_currentSelectedMeshItem); m_meshesCombo.ItemSelected += new MyGuiControlCombobox.ItemSelectedDelegate(meshesCombo_OnSelect); if (MySector.MainCamera != null) { m_voxelsCombo = AddCombo(); m_voxelsCombo.AddItem(-1, new StringBuilder("None")); int i = 0; foreach (var voxelMaterial in MyDefinitionManager.Static.GetVoxelMaterialDefinitions()) { m_voxelsCombo.AddItem(i++, new StringBuilder(voxelMaterial.Id.SubtypeName)); } m_voxelsCombo.SelectItemByIndex(m_currentSelectedVoxelItem + 1); m_voxelsCombo.ItemSelected += new MyGuiControlCombobox.ItemSelectedDelegate(voxelsCombo_OnSelect); } var selectedMesh = m_model.GetMeshList()[m_currentSelectedMeshItem]; var selectedMaterial = selectedMesh.Material; m_diffuseColor = AddColor(new StringBuilder("Diffuse"), selectedMaterial, MemberHelper.GetMember(() => selectedMaterial.DiffuseColor)); m_specularIntensity = AddSlider("Specular intensity", selectedMaterial.SpecularIntensity, 0, 32, null); m_specularPower = AddSlider("Specular power", selectedMaterial.SpecularPower, 0, 128, null); }
public static List<MyCubeBlockDefinition.MountPoint> AutogenerateMountpoints(MyModel model, float gridSize) { var shapes = model.HavokCollisionShapes; if (shapes == null) { if (model.HavokBreakableShapes == null) return new List<MyCubeBlockDefinition.MountPoint>(); shapes = new HkShape[] { model.HavokBreakableShapes[0].GetShape() }; } return AutogenerateMountpoints(shapes, gridSize); }
public void Initialize(MyModel animationModel, string playerName, int clipIndex, MySkinnedEntity skinnedEntity, float weight, float timeScale, MyFrameOption frameOption, string[] explicitBones = null, Dictionary<float, string[]> boneLODs = null) { if (m_hash != 0) { CachedAnimationPlayers.Remove(m_hash); m_hash = 0; } var clip = animationModel.Animations.Clips[clipIndex]; Name = MyStringId.GetOrCompute(animationModel.AssetName + " : " + playerName); m_duration = (float)clip.Duration; m_skinnedEntity = skinnedEntity; m_weight = weight; m_timeScale = timeScale; m_frameOption = frameOption; m_boneLODs.Clear(); var lod0 = new List<BoneInfo>(); m_boneLODs.Add(0, lod0); // Create the bone information classes var maxBoneCount = explicitBones == null ? clip.Bones.Count : explicitBones.Length; if (m_boneInfos == null || m_boneInfos.Length < maxBoneCount) m_boneInfos = new BoneInfo[maxBoneCount]; int neededBonesCount = 0; for (int b = 0; b < maxBoneCount; b++) { var bone = explicitBones == null ? clip.Bones[b] : FindBone(clip.Bones, explicitBones[b]); if (bone == null) continue; if (bone.Keyframes.Count == 0) continue; // Create it var boneInfo = new BoneInfo(bone, this); m_boneInfos[neededBonesCount] = boneInfo; // Assign it to a model bone m_boneInfos[neededBonesCount].SetModel(skinnedEntity); if (boneInfo.ModelBone != null) { lod0.Add(boneInfo); if (boneLODs != null) { foreach (var boneLOD in boneLODs) { List<BoneInfo> lodBones; if (!m_boneLODs.TryGetValue(boneLOD.Key, out lodBones)) { lodBones = new List<BoneInfo>(); m_boneLODs.Add(boneLOD.Key, lodBones); } foreach (var boneName in boneLOD.Value) { if (boneInfo.ModelBone.Name == boneName) { lodBones.Add(boneInfo); break; } } } } } neededBonesCount++; } m_boneCount = neededBonesCount; Position = 0; m_initialized = true; }
public void Init(MyModel model, Matrix matrix) { Model = model; InstanceData.LocalMatrix = matrix; model.LoadData(); }
public void GetTrianglesIntersectingSphere(MyModel model, ref BoundingSphereD sphere, Vector3? referenceNormalVector, float? maxAngle, List<MyTriangle_Vertex_Normals> retTriangles, int maxNeighbourTriangles) { // Check if sphere intersects bounding box of this node //if (m_boundingBox.Contains(sphere) == ContainmentType.Disjoint) return; if (m_boundingBox.Intersects(ref sphere) == false) return; // temporary variable for storing tirngle boundingbox info BoundingBox triangleBoundingBox = new BoundingBox(); // Triangles that are directly in this node for (int i = 0; i < m_triangleIndices.Count; i++) { // If we reached end of the buffer of neighbour triangles, we stop adding new ones. This is better behavior than throwing exception because of array overflow. if (retTriangles.Count == maxNeighbourTriangles) return; int triangleIndex = m_triangleIndices[i]; model.GetTriangleBoundingBox(triangleIndex, ref triangleBoundingBox); // First test intersection of triangleVertexes's bounding box with bounding sphere. And only if they overlap or intersect, do further intersection tests. if (triangleBoundingBox.Intersects(ref sphere)) { //if (m_triangleIndices[value] != ignoreTriangleWithIndex) { // See that we swaped vertex indices!! MyTriangle_Vertexes triangle; MyTriangle_Normals triangleNormals; //MyTriangle_Normals triangleTangents; MyTriangleVertexIndices triangleIndices = model.Triangles[triangleIndex]; triangle.Vertex0 = model.GetVertex(triangleIndices.I0); triangle.Vertex1 = model.GetVertex(triangleIndices.I2); triangle.Vertex2 = model.GetVertex(triangleIndices.I1); triangleNormals.Normal0 = model.GetVertexNormal(triangleIndices.I0); triangleNormals.Normal1 = model.GetVertexNormal(triangleIndices.I2); triangleNormals.Normal2 = model.GetVertexNormal(triangleIndices.I1); /* triangleTangents.Normal0 = model.GetVertexTangent(triangleIndices.I0); triangleTangents.Normal1 = model.GetVertexTangent(triangleIndices.I2); triangleTangents.Normal2 = model.GetVertexTangent(triangleIndices.I1); */ PlaneD trianglePlane = new PlaneD(triangle.Vertex0, triangle.Vertex1, triangle.Vertex2); if (MyUtils.GetSphereTriangleIntersection(ref sphere, ref trianglePlane, ref triangle) != null) { Vector3 triangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangle); if ((referenceNormalVector.HasValue == false) || (maxAngle.HasValue == false) || ((MyUtils.GetAngleBetweenVectors(referenceNormalVector.Value, triangleNormal) <= maxAngle))) { MyTriangle_Vertex_Normals retTriangle; retTriangle.Vertices = triangle; retTriangle.Normals = triangleNormals; // retTriangle.Tangents = triangleTangents; retTriangles.Add(retTriangle); } } } } } // Get intersection with childs of this node if (m_childs != null) { for (int i = 0; i < m_childs.Count; i++) { //m_childs[value].GetTrianglesIntersectingSphere(physObject, ref sphere, referenceNormalVector, maxAngle, ignoreTriangleWithIndex, retTriangles, maxNeighbourTriangles); m_childs[i].GetTrianglesIntersectingSphere(model, ref sphere, referenceNormalVector, maxAngle, retTriangles, maxNeighbourTriangles); } } }
// Return true if object intersects specified sphere. // This method doesn't return exact point of intersection or any additional data. // We don't look for closest intersection - so we stop on first intersection found. // IMPORTANT: Sphere must be in model space, so don't transform it! public bool GetIntersectionWithSphere(MyModel model, ref BoundingSphereD sphere) { // Check if sphere intersects bounding box of this node if (m_boundingBox.Intersects(ref sphere) == false) { return false; } // temporary variable for storing tirngle boundingbox info BoundingBox triangleBoundingBox = new BoundingBox(); // Triangles that are directly in this node for (int i = 0; i < m_triangleIndices.Count; i++) { int triangleIndex = m_triangleIndices[i]; model.GetTriangleBoundingBox(triangleIndex, ref triangleBoundingBox); // First test intersection of triangleVertexes's bounding box with bounding sphere. And only if they overlap or intersect, do further intersection tests. if (triangleBoundingBox.Intersects(ref sphere)) { // See that we swaped vertex indices!! MyTriangle_Vertexes triangle; MyTriangleVertexIndices triangleIndices = model.Triangles[triangleIndex]; triangle.Vertex0 = model.GetVertex(triangleIndices.I0); triangle.Vertex1 = model.GetVertex(triangleIndices.I2); triangle.Vertex2 = model.GetVertex(triangleIndices.I1); PlaneD trianglePlane = new PlaneD(triangle.Vertex0, triangle.Vertex1, triangle.Vertex2); if (MyUtils.GetSphereTriangleIntersection(ref sphere, ref trianglePlane, ref triangle) != null) { // If we found intersection we can stop and dont need to look further return true; } } } // Get intersection with childs of this node if (m_childs != null) { for (int i = 0; i < m_childs.Count; i++) { if (m_childs[i].GetIntersectionWithSphere(model, ref sphere)) { return true; } } } return false; }
private static void ExtractModelDataForObj( MyModel model, Matrix matrix, List<Vector3> vertices, List<TriangleWithMaterial> triangles, List<Vector2> uvs, ref Vector2 offsetUV, Dictionary<string, MyExportModel.Material> materials, ref int currVerticesCount, Vector3 colorMaskHSV) { if (false == model.HasUV) { model.LoadUV = true; model.UnloadData(); model.LoadData(); } MyExportModel renderModel = new MyExportModel(model); int modelVerticesCount = renderModel.GetVerticesCount(); List<HalfVector2> modelUVs = GetUVsForModel(renderModel, modelVerticesCount); Debug.Assert(modelUVs.Count == modelVerticesCount, "wrong UVs for model"); if (modelUVs.Count != modelVerticesCount) { return; } //we need new material for every HSV and texture combination, therefore we need to create new materials for each model List<MyExportModel.Material> newModelMaterials = CreateMaterialsForModel(materials, colorMaskHSV, renderModel); for (int i = 0; i < modelVerticesCount; ++i) { vertices.Add(Vector3.Transform(model.GetVertex(i), matrix)); Vector2 localUV = modelUVs[i].ToVector2()/model.PatternScale + offsetUV; uvs.Add(new Vector2(localUV.X, -localUV.Y)); } for (int i = 0; i < renderModel.GetTrianglesCount(); ++i) { int matID = -1; for (int j = 0; j < newModelMaterials.Count; ++j) { if (i <= newModelMaterials[j].LastTri) { matID = j; break; } } Debug.Assert(matID != -1, "Triangle with no material"); var t = renderModel.GetTriangle(i); string materialName = "EmptyMaterial"; if (matID != -1) { materialName = newModelMaterials[matID].Name; } triangles.Add(new TriangleWithMaterial() { triangle = new MyTriangleVertexIndices(t.I0 + 1 + currVerticesCount, t.I1 + 1 + currVerticesCount, t.I2 + 1 + currVerticesCount), material = materialName, }); } currVerticesCount += modelVerticesCount; }
// Difference between GetIntersectionWithLine and GetIntersectionWithLineRecursive is that the later doesn't calculate // final result, but is better suited for recursive nature of octree. Don't call GetIntersectionWithLineRecursive() from // the outisde of this class, it's private method. public MyIntersectionResultLineTriangleEx? GetIntersectionWithLine(IMyEntity physObject, MyModel model, ref LineD line, double? minDistanceUntilNow, IntersectionFlags flags) { MyIntersectionResultLineTriangle? foundTriangle = GetIntersectionWithLineRecursive(model, ref line, minDistanceUntilNow); if (foundTriangle != null) { return new MyIntersectionResultLineTriangleEx(foundTriangle.Value, physObject, ref line); } else { return null; } }
public MyExportModel(MyModel model) { m_model = model; m_model.LoadData(); ExtractMaterialsFromModel(); }
IPhysicsMesh CreatePhysicsMesh(MyModel model) { IPhysicsMesh physicsMesh = new MyPhysicsMesh(); physicsMesh.SetAABB(model.BoundingBox.Min, model.BoundingBox.Max); for (int v = 0; v < model.GetVerticesCount(); v++) { Vector3 vertex = model.GetVertex(v); Vector3 normal = model.GetVertexNormal(v); Vector3 tangent = model.GetVertexTangent(v); if (model.TexCoords == null) model.LoadTexCoordData(); Vector2 texCoord = model.TexCoords[v].ToVector2(); physicsMesh.AddVertex(vertex, normal, tangent, texCoord); } for (int i = 0; i < model.Indices16.Length; i++) { physicsMesh.AddIndex(model.Indices16[i]); } for (int i = 0; i < model.GetMeshList().Count; i++) { var mesh = model.GetMeshList()[i]; physicsMesh.AddSectionData(mesh.IndexStart, mesh.TriCount, mesh.Material.Name); } return physicsMesh; }
public static void InitSpherePhysics(this IMyEntity entity, MyStringHash materialType, MyModel model, float mass, float linearDamping, float angularDamping, ushort collisionLayer, RigidBodyFlag rbFlag) { Debug.Assert(model != null); entity.InitSpherePhysics(materialType, model.BoundingSphere.Center, model.BoundingSphere.Radius, mass, linearDamping, angularDamping, collisionLayer, rbFlag); }
private void CreatePieceData(MyModel model, HkdBreakableShape breakableShape) { //Root shape for fractured compound blocks { var msg = VRageRender.MyRenderProxy.PrepareAddRuntimeModel(); ProfilerShort.Begin("GetDataFromShape"); m_tmpMesh.Data = msg.ModelData; MyDestructionData.Static.Storage.GetDataFromShape(breakableShape, m_tmpMesh); System.Diagnostics.Debug.Assert(msg.ModelData.Sections.Count > 0, "Invalid data"); if (msg.ModelData.Sections.Count > 0) { if(MyFakes.USE_HAVOK_MODELS) msg.ReplacedModel = model.AssetName; VRageRender.MyRenderProxy.AddRuntimeModel(breakableShape.ShapeName, msg); } ProfilerShort.End(); } using (m_tmpChildrenList.GetClearToken()) { breakableShape.GetChildren(m_tmpChildrenList); LoadChildrenShapes(m_tmpChildrenList); } }
public static void InitBoxPhysics(this IMyEntity entity, MyStringHash materialType, MyModel model, float mass, float angularDamping, ushort collisionLayer, RigidBodyFlag rbFlag) { Debug.Assert(model != null); var center = model.BoundingBox.Center; var size = model.BoundingBoxSize; entity.InitBoxPhysics(materialType, center, size, mass, 0, angularDamping, collisionLayer, rbFlag); }
public static MyModel GetModelOnlyModelInfo(string modelAsset) { Debug.Assert(modelAsset != null); MyModel model; if (!m_models.TryGetValue(modelAsset, out model)) { model = new MyModel(modelAsset); m_models[modelAsset] = model; } model.LoadOnlyModelInfo(); return model; }
/// <summary> /// Adds item physics shape to rootShape and returns instance id of added shape instance. /// </summary> /// <returns>true if ite physics shape has been added, otherwise false.</returns> private bool AddPhysicsShape(MyStringHash subtypeId, MyModel model, ref MatrixD worldMatrix, HkStaticCompoundShape sectorRootShape, Dictionary<MyStringHash, HkShape> subtypeIdToShape, out int physicsShapeInstanceId) { physicsShapeInstanceId = 0; HkShape physicsShape; if (!subtypeIdToShape.TryGetValue(subtypeId, out physicsShape)) { HkShape[] shapes = model.HavokCollisionShapes; if (shapes == null || shapes.Length == 0) return false; Debug.Assert(shapes.Length == 1); //List<HkShape> listShapes = new List<HkShape>(); //for (int i = 0; i < shapes.Length; i++) //{ // listShapes.Add(shapes[i]); // HkShape.SetUserData(shapes[i], shapes[i].UserData | (int)HkShapeUserDataFlags.EnvironmentItem); //} //physicsShape = new HkListShape(listShapes.GetInternalArray(), listShapes.Count, HkReferencePolicy.None); //HkShape.SetUserData(physicsShape, physicsShape.UserData | (int)HkShapeUserDataFlags.EnvironmentItem); physicsShape = shapes[0]; physicsShape.AddReference(); subtypeIdToShape[subtypeId] = physicsShape; } if (physicsShape.ReferenceCount != 0) { Matrix localMatrix = worldMatrix * MatrixD.CreateTranslation(-CellsOffset); physicsShapeInstanceId = sectorRootShape.AddInstance(physicsShape, localMatrix); Debug.Assert(physicsShapeInstanceId >= 0 && physicsShapeInstanceId < int.MaxValue, "Shape key space overflow"); return true; } else { return false; } }
// Lazy-loading and then returning reference to model public static MyModel GetModelOnlyAnimationData(string modelAsset) { MyModel model; if (!m_models.TryGetValue(modelAsset, out model)) { model = new MyModel(modelAsset); m_models[modelAsset] = model; } model.LoadAnimationData(); return model; }
public MyQuantizedBvhAdapter(GImpactQuantizedBvh bvh, MyModel model) { m_bvh = bvh; m_model = model; }