Exemplo n.º 1
0
        public void BeginDraw_Ray(Ray3f ray, AnyRayHit rayHit, int nStep)
        {
            CreateNewPrimitive();

            Vector3f hitPos = rayHit.hitPos;

            // try snap points
            SnapResult snap = Snaps.FindHitSnapPoint(ray);

            if (snap != null)
            {
                Frame3f snapF = scene.ToWorldFrame(snap.FrameS);
                hitPos = snapF.Origin;
            }

            Frame3f sceneW = scene.SceneFrame;

            if (rayHit.hitSO == null)
            {
                primStartW        = sceneW;
                primStartW.Origin = hitPos;
            }
            else
            {
                if (scene.Context.TransformManager.ActiveFrameType == FrameType.WorldFrame)
                {
                    primStartW        = sceneW;
                    primStartW.Origin = hitPos;
                }
                else if (rayHit.hitSO is PivotSO)
                {
                    primStartW        = (rayHit.hitSO as PivotSO).GetLocalFrame(CoordSpace.WorldCoords);
                    primStartW.Origin = hitPos;
                }
                else if (rayHit.hitSO is PrimitiveSO)
                {
                    // align with object frame as much as possible, given that we still want
                    //  to use hit normal...
                    Frame3f objFrame  = (rayHit.hitSO as PrimitiveSO).GetLocalFrame(CoordSpace.WorldCoords);
                    int     nBestAxis = MathUtil.MostParallelAxis(objFrame, rayHit.hitNormal);
                    int     nPerp     = (nBestAxis + 1) % 3;
                    primStartW = new Frame3f(hitPos, rayHit.hitNormal, 1);
                    primStartW.ConstrainedAlignAxis(0, objFrame.GetAxis(nPerp), primStartW.Y);
                }
                else
                {
                    primStartW = new Frame3f(hitPos, rayHit.hitNormal, 1);
                    primStartW.ConstrainedAlignAxis(1, sceneW.Y, primStartW.Y);
                }
            }
            primitive.Frame = primStartW;
            primStartS      = scene.ToSceneFrame(primStartW);
        }
Exemplo n.º 2
0
        void update_position(AnyRayHit hit)
        {
            int nNormalAxis = 1;
            int nUpAxis     = 2;

            // as we drag object we will align Y with hit surface normal, but
            // we also want to constrain rotation so it is stable. Hence, we are
            // going to use world or local frame of target object to stabilize
            // rotation around normal.
            Frame3f hitF       = TargetScene.SceneFrame;
            Vector3 targetAxis = hitF.GetAxis(1);

            if (hit.hitSO is SceneObject)
            {
                hitF = (hit.hitSO as SceneObject).GetLocalFrame(CoordSpace.WorldCoords);
            }
            bool bUseLocal =
                (TargetScene.Context.TransformManager.ActiveFrameType == FrameType.LocalFrame);

            if (bUseLocal && hit.hitSO is SceneObject)
            {
                hitF       = (hit.hitSO as SceneObject).GetLocalFrame(CoordSpace.WorldCoords);
                targetAxis = hitF.GetAxis(1);
            }
            // if normal is parallel to target, this would become unstable, so use another axis
            if (Vector3.Dot(targetAxis, hit.hitNormal) > 0.99f)
            {
                targetAxis = hitF.GetAxis(0);
            }

            if (lastHitObject == null || hit.hitSO != lastHitObject)
            {
                lastHitF = new Frame3f(hit.hitPos, hit.hitNormal, nNormalAxis);
                lastHitF.ConstrainedAlignAxis(nUpAxis, targetAxis, lastHitF.GetAxis(nNormalAxis));
            }
            else
            {
                lastHitF.Origin = hit.hitPos;
                lastHitF.AlignAxis(nNormalAxis, hit.hitNormal);
                lastHitF.ConstrainedAlignAxis(nUpAxis, targetAxis, lastHitF.GetAxis(nNormalAxis));
            }
            lastHitObject = hit.hitSO;
        }
    // Use this for initialization
    public override void Awake()
    {
        // if we need to auto-configure Rift vs Vive vs (?) VR, we need
        // to do this before any other F3 setup, because MainCamera will change
        // and we are caching that in a lot of places...
        if (AutoConfigVR)
        {
            VRCameraRig = gs.VRPlatform.AutoConfigureVR();
        }

        // restore any settings
        SceneGraphConfig.RestorePreferences();

        // set up some defaults
        // this will move the ground plane down, but the bunnies will be floating...
        //SceneGraphConfig.InitialSceneTranslate = -4.0f * Vector3f.AxisY;
        SceneGraphConfig.DefaultSceneCurveVisualDegrees = 0.5f;
        SceneGraphConfig.DefaultPivotVisualDegrees      = 1.5f;
        SceneGraphConfig.DefaultAxisGizmoVisualDegrees  = 10.0f;
        SceneGraphConfig.InitialSceneTranslate          = -4 * Vector3f.AxisY;


        SceneOptions options = new SceneOptions();

        options.UseSystemMouseCursor = false;
        options.Use2DCockpit         = false;
        options.EnableTransforms     = true;
        options.EnableCockpit        = true;
        options.CockpitInitializer   = new PhotoToolCockpit();

        options.MouseCameraControls = new MayaCameraHotkeys();
        options.SpatialCameraRig    = VRCameraRig;

        // very verbose
        options.LogLevel = 2;

        context = new FContext();
        context.Start(options);

        // if you had other gizmos, you would register them here
        //context.TransformManager.RegisterGizmoType("snap_drag", new SnapDragGizmoBuilder());
        //controller.TransformManager.SetActiveGizmoType("snap_drag");

        // if you had other tools, you would register them here.
        context.ToolManager.RegisterToolType(DrawPrimitivesTool.Identifier, new DrawPrimitivesToolBuilder());
        context.ToolManager.RegisterToolType(DrawSurfaceCurveTool.Identifier, new DrawSurfaceCurveToolBuilder()
        {
            AttachCurveToSurface = true,
            DefaultSamplingRateS = 0.0025f, DefaultSurfaceOffsetS = 0.0025f,
            CurveMaterialF       = () => { var mat = context.Scene.DefaultCurveSOMaterial.Clone(); mat.RGBColor = Colorf.VideoRed; return(mat); }
        });
        context.ToolManager.SetActiveToolType(DrawSurfaceCurveTool.Identifier, ToolSide.Right);

        // Set up standard scene lighting if requested
        if (options.EnableDefaultLighting)
        {
            GameObject lighting = GameObject.Find("SceneLighting");
            if (lighting == null)
            {
                lighting = new GameObject("SceneLighting");
            }
            SceneLightingSetup setup = lighting.AddComponent <SceneLightingSetup>();
            setup.Context       = context;
            setup.LightDistance = 30.0f; // related to total scene scale...
        }


        Context.Scene.DisableSelectionMaterial = true;


        /*
         * Import elements of Unity scene that already exist into the FScene
         */

        // set up ground plane geometry (optional)
        GameObject groundPlane = GameObject.Find("GroundPlane");

        if (groundPlane != null && groundPlane.IsVisible())
        {
            context.Scene.AddWorldBoundsObject(groundPlane);
        }


        float    fSquareSize = 1.0f;
        Vector3f eyePos      = context.ActiveCamera.GetPosition();

        System.Random rand = new System.Random(31337);

        // [RMS] this path only works in Editor, is relative to top-level project directory
        string sPhotoFolder = "Data\\PhotoSets\\kitchen";

        string[] photos = Directory.GetFiles(sPhotoFolder);
        foreach (string filename in photos)
        {
            Texture2D tex = load_texture(filename);
            if (tex == null)
            {
                continue;
            }

            float fScale = fSquareSize / (float)tex.width;
            if (tex.height > tex.width)
            {
                fScale = fSquareSize / (float)tex.height;
            }

            float w = fScale * (float)tex.width;
            float h = fScale * (float)tex.height;

            TrivialRectGenerator rectgen = new TrivialRectGenerator()
            {
                Width = w, Height = h
            };
            rectgen.Generate();
            DMesh3 mesh = new DMesh3(MeshComponents.VertexUVs);
            rectgen.MakeMesh(mesh);

            SOMaterial material = new SOMaterial()
            {
                Name     = "photomaterial",
                Type     = SOMaterial.MaterialType.TextureMap,
                RGBColor = Colorf.White
            };
            material.MainTexture = tex;

            DMeshSO so = new DMeshSO();
            so.Create(mesh, material);
            context.Scene.AddSceneObject(so);

            float horz = rand.Next(-50, 50);
            float vert = rand.Next(-20, 25);
            int   mult = 1000;
            float dist = (float)(rand.Next(2 * mult, 3 * mult)) / (float)mult;

            Ray3f r = VRUtil.MakeRayFromSphereCenter(horz, vert);
            r.Origin += eyePos;
            float fRayT = 0.0f;
            RayIntersection.Sphere(r.Origin, r.Direction, eyePos, dist, out fRayT);
            Vector3f v = r.Origin + fRayT * r.Direction;
            Frame3f  f = new Frame3f(v, v.Normalized);

            Vector3f toEye = context.ActiveCamera.GetPosition() - f.Origin;
            toEye.Normalize();
            f.AlignAxis(1, toEye);
            f.ConstrainedAlignAxis(2, Vector3f.AxisY, f.Y);

            so.SetLocalFrame(f, CoordSpace.WorldCoords);
        }
    }
Exemplo n.º 4
0
        public void UpdateTracking(Cockpit cockpit, fCamera camera)
        {
            fGameObject cockpitGO = cockpit.RootGameObject;

            if (!bInitialized)
            {
                currentFrame = cockpit.GetLevelViewFrame(CoordSpace.WorldCoords);
                currentFrame.ConstrainedAlignAxis(2, Vector3f.AxisZ, Vector3f.AxisY);
                bInitialized = true;
            }

            Vector3f vCamFW = camera.Forward();

            vCamFW[1] = 0; vCamFW.Normalize();      // I don't think this is strictly necessary but
                                                    // better to be safe for now...
            Vector3f vCamPos = camera.GetPosition();

            //if (tracking_debug == null)
            //    tracking_debug = UnityUtil.CreatePrimitiveGO("tracking_indicator", PrimitiveType.Sphere, MaterialUtil.CreateStandardMaterial(Color.green), false);
            //tracking_debug.transform.position = vCamPos + 15.0f * vCamFW;

            //if (tracking_avg == null) {
            //    tracking_avg = UnityUtil.CreatePrimitiveGO("tracking_indicator", PrimitiveType.Sphere, MaterialUtil.CreateStandardMaterial(Color.blue), false);
            //    tracking_avg.transform.localScale = new Vector3(0.5f, 0.5f, 0.5f);
            //}
            //tracking_avg.transform.position = vCamPos + 10.0f * vSlowViewDirTrack;

            //tracking_debug.SetVisible(false);
            //tracking_avg.SetVisible(false);

            if (vSlowViewDirTrack == Vector3f.Zero)
            {
                vSlowViewDirTrack = vCamFW;
            }

            float slowTrackSpeed = 0.05f;

            vSlowViewDirTrack = VRUtil.AngleLerp(vSlowViewDirTrack, vCamFW, slowTrackSpeed);


            // head position tracking
            if (IsLocked == false)
            {
                cockpitGO.SetPosition(vCamPos);
            }
            //Vector3 vDelta = (camera.transform.position - RootGameObject.transform.position);
            //if (vDelta.magnitude > 0.2f)
            //    RootGameObject.transform.position = camera.transform.position;
            ////else if ( vDelta.magnitude > 0.05f)
            //else
            //    RootGameObject.transform.position =
            //        (1.0f - TrackingSpeed) * RootGameObject.transform.position +
            //        (TrackingSpeed) * camera.transform.position;


            float RotationSpeed                = 200.0f;
            float WarmupTrackingAngleThresh    = 55.0f;
            float ImmediateTrackingAngleThresh = 65.0f;
            float StopTrackingAngleThresh      = 5.0f;
            float TrackingWarmupDelay          = 2.0f;
            float TrackingCooldownDelay        = 0.75f;


            //Vector3 vCockpitFW = cockpitGO.transform.forward;
            Vector3f vCockpitFW = currentFrame.Z;

            float fSlowHDeviation      = VRUtil.PlaneAngle(vCockpitFW, vSlowViewDirTrack);
            float fActualViewDeviation = VRUtil.PlaneAngle(vCockpitFW, vCamFW);

            bool bDoTrack = false;

            if (eState == TrackingState.NotTracking)
            {
                //tracking_debug.GetComponent<Renderer>().material = MaterialUtil.CreateStandardMaterial(Color.green);
                if (fSlowHDeviation > WarmupTrackingAngleThresh)
                {
                    set_tracking_state(TrackingState.TrackingWarmup);
                    stateChangeStartTime = FPlatform.RealTime();
                }
            }
            else if (eState == TrackingState.TrackingWarmup)
            {
                //tracking_debug.GetComponent<Renderer>().material = MaterialUtil.CreateStandardMaterial(Color.yellow);
                if (fSlowHDeviation > ImmediateTrackingAngleThresh)
                {
                    set_tracking_state(TrackingState.Tracking);
                }
                else if (fSlowHDeviation > WarmupTrackingAngleThresh)
                {
                    if ((FPlatform.RealTime() - stateChangeStartTime) > TrackingWarmupDelay)
                    {
                        set_tracking_state(TrackingState.Tracking);
                    }
                }
                else
                {
                    set_tracking_state(TrackingState.NotTracking);
                }
            }
            else if (eState == TrackingState.Tracking)
            {
                bDoTrack = true;
                //tracking_debug.GetComponent<Renderer>().material = MaterialUtil.CreateStandardMaterial(Color.red);
                if (fActualViewDeviation < StopTrackingAngleThresh)
                {
                    set_tracking_state(TrackingState.TrackingCooldown);
                    stateChangeStartTime = FPlatform.RealTime();
                }
            }
            else if (eState == TrackingState.TrackingCooldown)
            {
                bDoTrack = true;
                //tracking_debug.GetComponent<Renderer>().material = MaterialUtil.CreateStandardMaterial(Color.gray);
                if (fActualViewDeviation < StopTrackingAngleThresh)
                {
                    if ((FPlatform.RealTime() - stateChangeStartTime) > TrackingCooldownDelay)
                    {
                        set_tracking_state(TrackingState.NotTracking);
                        bDoTrack = false;
                    }
                }
                else
                {
                    set_tracking_state(TrackingState.Tracking);
                }
            }

            if (IsLocked)
            {
                bDoTrack = false;
                set_tracking_state(TrackingState.NotTracking);
            }


            if (bDoTrack)
            {
                float dt     = (float)(FPlatform.RealTime() - animation_last_time);
                float fDelta = RotationSpeed * dt;

                Vector3f vCurrent = new Vector3f(vCockpitFW[0], 0, vCockpitFW[2]).Normalized;
                Vector3f vTarget  = new Vector3f(vSlowViewDirTrack[0], 0, vSlowViewDirTrack[2]).Normalized;
                //Vector3 vTarget = new Vector3(vCamFW[0], 0, vCamFW[2]).normalized;
                Vector3f c     = Vector3f.Cross(vCurrent, vTarget);
                float    a     = Vector3f.AngleD(vCurrent, vTarget);
                float    fSign = (c[1] < 0) ? -1.0f : 1.0f;

                float fRotAngle = Math.Min(a, fDelta) * fSign;

                currentFrame.Rotate(Quaternionf.AxisAngleD(Vector3f.AxisY, fRotAngle));
            }
            cockpitGO.SetRotation(currentFrame.Rotation);
            animation_last_time = FPlatform.RealTime();


            if (indicator == null)
            {
                indicator = new CockpitTrackingWidget();
                indicator.Create(this, cockpit);
                cockpit.AddUIElement(indicator, false);
            }
            indicator.EnableIndicator = show_indicator;
        }
Exemplo n.º 5
0
        public static void quick_test()
        {
            DMesh3         mesh    = StandardMeshReader.ReadMesh("c:\\scratch\\block.obj");
            DMeshAABBTree3 spatial = new DMeshAABBTree3(mesh, true);

            Vector3d rayCenter = new Vector3d(0, 0, 1);
            Frame3f  rayFrame  = new Frame3f(rayCenter, Vector3d.AxisZ);

            List <Frame3f> frames = new List <Frame3f>();

            // how far into surface we will inset
            float SurfaceOffset = 0.01f;

            double step = 2.5f;

            for (double angle = 0; angle < 360; angle += step)
            {
                double dx    = Math.Cos(angle * MathUtil.Deg2Rad),
                       dy    = Math.Sin(angle * MathUtil.Deg2Rad);
                Vector3d dir = dx * (Vector3d)rayFrame.X + dy * (Vector3d)rayFrame.Y;
                Ray3d    ray = new Ray3d(rayFrame.Origin, dir.Normalized);

                Frame3f hitFrame;
                if (MeshQueries.RayHitPointFrame(mesh, spatial, ray, out hitFrame))
                {
                    frames.Add(hitFrame);
                }
            }

            int N = frames.Count;

            for (int k = 0; k < N; ++k)
            {
                Frame3f f    = frames[k];
                int     prev = (k == 0) ? N - 1 : k - 1;
                int     next = (k + 1) % N;
                //Vector3f dv = frames[(k + 1) % frames.Count].Origin - f.Origin;
                Vector3f dv = frames[next].Origin - frames[prev].Origin;
                dv.Normalize();
                f.ConstrainedAlignAxis(0, dv, f.Z);

                f.Origin = f.Origin + SurfaceOffset * f.Z;

                frames[k] = f;
            }

            //Frame3f f = frames[0];
            //Vector3f dv = (frames[1].Origin - frames[0].Origin).Normalized;
            //f.ConstrainedAlignAxis(1, dv, f.Z);
            //for (int k = 1; k < frames.Count; ++k) {
            //    f.Origin = frames[k].Origin;
            //    f.AlignAxis(2, frames[k].Z);
            //    frames[k] = f;
            //}


            List <Vector3d> vertices = frames.ConvertAll((ff) => { return((Vector3d)ff.Origin); });

            TubeGenerator tubegen = new TubeGenerator()
            {
                Vertices         = vertices,
                Polygon          = Polygon2d.MakeCircle(0.05, 16),
                NoSharedVertices = false
            };
            DMesh3 tubeMesh = tubegen.Generate().MakeDMesh();

            TestUtil.WriteTestOutputMeshes(new List <IMesh>()
            {
                mesh, tubeMesh
            }, "curve_tube.obj");


            SimpleQuadMesh stripMeshY = new SimpleQuadMesh();
            double         w = 0.1;
            int            preva = -1, prevb = -1;

            for (int k = 0; k < N; ++k)
            {
                Vector3d pa = frames[k].Origin + w * (Vector3d)frames[k].Y;
                Vector3d pb = frames[k].Origin - w * (Vector3d)frames[k].Y;
                int      a  = stripMeshY.AppendVertex(pa);
                int      b  = stripMeshY.AppendVertex(pb);
                if (preva != -1)
                {
                    stripMeshY.AppendQuad(preva, prevb, b, a);
                }
                preva = a; prevb = b;
            }
            stripMeshY.AppendQuad(preva, prevb, 1, 0);
            SimpleQuadMesh.WriteOBJ(stripMeshY, TEST_OUTPUT_PATH + "quadstripy.obj", WriteOptions.Defaults);



            SimpleQuadMesh stripMeshZ = new SimpleQuadMesh();

            preva = -1; prevb = -1;
            double wz = 0.1;

            for (int k = 0; k < N; ++k)
            {
                Vector3d pa = frames[k].Origin + wz * (Vector3d)frames[k].Z;
                Vector3d pb = frames[k].Origin - wz * (Vector3d)frames[k].Z;
                int      a  = stripMeshZ.AppendVertex(pa);
                int      b  = stripMeshZ.AppendVertex(pb);
                if (preva != -1)
                {
                    stripMeshZ.AppendQuad(preva, prevb, b, a);
                }
                preva = a; prevb = b;
            }
            stripMeshZ.AppendQuad(preva, prevb, 1, 0);
            SimpleQuadMesh.WriteOBJ(stripMeshZ, TEST_OUTPUT_PATH + "quadstripz.obj", WriteOptions.Defaults);
        }