예제 #1
0
        //  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;
        }
예제 #2
0
        //  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);
            }

        }
예제 #5
0
        //  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();
        }
예제 #7
0
        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);
        }
예제 #9
0
        // 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;
        }
예제 #10
0
        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);
        }
예제 #12
0
        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);
        }
예제 #13
0
        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;
        }
예제 #14
0
 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;
        }
예제 #17
0
        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;
            }
        }
예제 #19
0
 public MyExportModel(MyModel model)
 {
     m_model = model;
     m_model.LoadData();
     ExtractMaterialsFromModel();
 }
예제 #20
0
        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;
        }
예제 #21
0
 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);
 }
예제 #22
0
        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);
            }
        }
예제 #23
0
 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);
 }
예제 #24
0
        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;

        }
예제 #25
0
        /// <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;
            }
        }
예제 #26
0
        //  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;
 }