Ejemplo n.º 1
0
        protected override void update_vertices(FScene s)
        {
            // [RMS] this was commented out...doesn't work? something?
            //if (Target.Timestamp == target_timestamp)
            //    return;

            //target_timestamp = Target.Timestamp;

            for (int i = 0; i < VertexCount; ++i)
            {
                LocalVertexRef r      = SurfacePoints[i];
                Vector3d       vScene = SceneTransforms.ObjectToSceneP(Target, r.localPos);
                this[i] = vScene;
            }
        }
Ejemplo n.º 2
0
        override public bool FindRayIntersection(Ray3f worldRay, out SORayHit hit)
        {
            hit = null;

            // project world ray into local coords
            FScene scene    = GetScene();
            Ray3f  sceneRay = scene.ToSceneRay(worldRay);
            Ray3f  localRay = SceneTransforms.SceneToObject(this, sceneRay);

            // also need width in local coords
            float sceneWidth = scene.ToSceneDimension(visibleWidth);
            float localWidth = SceneTransforms.SceneToObject(this, sceneWidth) * HitWidthMultiplier;

            // bounding-box hit test (would be nice to do w/o object allocation...)
            AxisAlignedBox3d hitBox = localBounds;

            hitBox.Expand(localWidth);
            IntrRay3AxisAlignedBox3 box_test = new IntrRay3AxisAlignedBox3(localRay, hitBox);

            if (box_test.Find() == false)
            {
                return(false);
            }

            // raycast against curve (todo: spatial data structure for this? like 2D polycurve bbox tree?)
            double rayHitT;

            if (CurveUtils.FindClosestRayIntersection(curve, localWidth, localRay, out rayHitT))
            {
                hit = new SORayHit();
                // transform local hit point back into world coords
                Vector3f rayPos   = localRay.PointAt((float)rayHitT);
                Vector3f scenePos = SceneTransforms.ObjectToSceneP(this, rayPos);
                hit.hitPos    = SceneTransforms.SceneToWorldP(scene, scenePos);
                hit.fHitDist  = worldRay.Project(hit.hitPos);
                hit.hitNormal = Vector3f.Zero;
                hit.hitGO     = root;
                hit.hitSO     = this;
                return(true);
            }
            return(false);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Find intersection of *WORLD* ray with Mesh
        /// </summary>
        override public bool FindRayIntersection(Ray3f rayW, out SORayHit hit)
        {
            hit = null;
            if (enable_spatial == false)
            {
                return(false);
            }

            validate_spatial();

            // convert ray to local
            FScene scene     = this.GetScene();
            Ray3f  rayS      = scene.ToSceneRay(rayW);
            Ray3d  local_ray = SceneTransforms.SceneToObject(this, rayS);

            int hit_tid = spatial.FindNearestHitTriangle(local_ray);

            if (hit_tid != DMesh3.InvalidID)
            {
                IntrRay3Triangle3 intr = MeshQueries.TriangleIntersection(mesh, hit_tid, local_ray);

                Vector3f hitPos = (Vector3f)local_ray.PointAt(intr.RayParameter);
                hitPos = SceneTransforms.ObjectToSceneP(this, hitPos);
                hitPos = scene.ToWorldP(hitPos);

                Vector3f hitNormal = (Vector3f)mesh.GetTriNormal(hit_tid);
                hitNormal = SceneTransforms.ObjectToSceneN(this, hitNormal);
                hitNormal = scene.ToWorldN(hitNormal);

                hit           = new SORayHit();
                hit.hitPos    = hitPos;
                hit.hitNormal = hitNormal;
                hit.hitIndex  = hit_tid;
                hit.fHitDist  = hit.hitPos.Distance(rayW.Origin);   // simpler than transforming!
                hit.hitGO     = RootGameObject;
                hit.hitSO     = this;
                return(true);
            }
            return(false);
        }
Ejemplo n.º 4
0
        public virtual ExportStatus Export(FScene scene, string filename)
        {
            int[]            vertexMap = new int[2048]; // temp
            List <WriteMesh> vMeshes   = new List <WriteMesh>();

            if (WriteFaceGroups)
            {
                throw new Exception("SceneMeshExporter.Export: writing face groups has not yet been implemented!");
            }

            // extract all the mesh data we want to export
            foreach (SceneObject so in scene.SceneObjects)
            {
                if (so.IsTemporary || so.IsSurface == false || SceneUtil.IsVisible(so) == false)
                {
                    continue;
                }
                if (SOFilterF != null && SOFilterF(so) == false)
                {
                    continue;
                }

                // if this SO has an internal mesh we can just copy, use it
                if (so is DMeshSO)
                {
                    DMeshSO meshSO = so as DMeshSO;

                    // todo: flags

                    // make a copy of mesh
                    DMesh3 m = GetMeshForDMeshSO(meshSO);

                    // transform to scene coords and swap left/right
                    foreach (int vid in m.VertexIndices())
                    {
                        Vector3f v = (Vector3f)m.GetVertex(vid);
                        v = SceneTransforms.ObjectToSceneP(meshSO, v);
                        v = MeshTransforms.FlipLeftRightCoordSystems(v);
                        m.SetVertex(vid, v);
                    }
                    m.ReverseOrientation();

                    vMeshes.Add(new WriteMesh(m, so.Name));
                }


                // Look for lower-level fGameObject items to export. By default
                // this is anything with a MeshFilter, override CollectGOChildren
                // or use GOFilterF to add restrictions
                List <fGameObject> vExports = CollectGOChildren(so);
                if (vExports.Count > 0)
                {
                    SimpleMesh m = new SimpleMesh();
                    m.Initialize(WriteNormals, WriteVertexColors, WriteUVs, WriteFaceGroups);
                    int groupCounter = 1;

                    foreach (fGameObject childgo in vExports)
                    {
                        if (GOFilterF != null && GOFilterF(so, childgo) == false)
                        {
                            continue;
                        }

                        if (AppendGOMesh(childgo, m, vertexMap, scene, groupCounter))
                        {
                            groupCounter++;
                        }
                    }

                    vMeshes.Add(new WriteMesh(m, so.Name));
                }
            }


            // ok, we are independent of Scene now and can write in bg thread
            if (WriteInBackgroundThreads)
            {
                ExportStatus status = new ExportStatus()
                {
                    Exporter = this, IsComputing = true
                };
                WriteOptions useOptions = Options;
                useOptions.ProgressFunc = (cur, max) => {
                    status.Progress    = cur;
                    status.MaxProgress = max;
                };
                BackgroundWriteThread t = new BackgroundWriteThread()
                {
                    Meshes      = vMeshes, options = useOptions, Filename = filename,
                    CompletionF = (result) => {
                        LastWriteStatus         = result.code;
                        LastErrorMessage        = result.message;
                        status.LastErrorMessage = result.message;
                        status.Ok          = (result.code == IOCode.Ok);
                        status.IsComputing = false;
                        if (BackgroundWriteCompleteF != null)
                        {
                            BackgroundWriteCompleteF(this, status);
                        }
                    }
                };
                t.Start();
                return(status);
            }
            else
            {
                IOWriteResult result = StandardMeshWriter.WriteFile(filename, vMeshes, Options);
                LastWriteStatus  = result.code;
                LastErrorMessage = result.message;
                return(new ExportStatus()
                {
                    Exporter = this, IsComputing = false,
                    Ok = (result.code == IOCode.Ok),
                    LastErrorMessage = result.message
                });
            }
        }