//if running on a fixed timestep, this might be called //more often with a smaller delta time than RenderUpdate() internal void Update(UpdateTimer time, List <Input.InputAction> actions) { //Thread.Sleep(30); float secDelta = time.GetUpdateDeltaSeconds(); float msDelta = time.GetUpdateDeltaMilliSeconds(); mGD.GCam.Update(Vector3.Zero, 0f, 0f, 0f); }
internal void Update(UpdateTimer time, List <Input.InputAction> actions) { mFrameCheck++; Vector3 startPos = mGD.GCam.Position; Vector3 endPos = startPos + mGD.GCam.Forward * -2000f; float deltaMS = time.GetUpdateDeltaMilliSeconds(); float deltaSec = time.GetUpdateDeltaSeconds(); //animate characters for (int i = 0; i < mCharacters.Count; i++) { Character c = mCharacters[i]; c.Update(deltaSec); float totTime = mCharAnims.GetAnimTime(mAnims[mCurAnims[i]]); float strTime = mCharAnims.GetAnimStartTime(mAnims[mCurAnims[i]]); float endTime = totTime + strTime; mAnimTimes[i] += deltaSec; if (mAnimTimes[i] > endTime) { mAnimTimes[i] = strTime + (mAnimTimes[i] - endTime); } c.Animate(mAnims[mCurAnims[i]], mAnimTimes[i]); mCBones[i] = (mCharToArch[c] as CharacterArch).GetBoneTransforms(mCharAnims.GetSkeleton()); } //check for keys foreach (Input.InputAction act in actions) { if (act.mAction.Equals(Program.MyActions.NextCharacter)) { mCurChar++; if (mCurChar >= mCharacters.Count) { mCurChar = 0; } UpdateCAStatus(); } else if (act.mAction.Equals(Program.MyActions.NextStatic)) { mCurStatic++; if (mCurStatic >= mMeshes.Count) { mCurStatic = 0; } UpdateStaticStatus(); } else if (act.mAction.Equals(Program.MyActions.NextAnim)) { if (mCharacters.Count > 0) { mCurAnims[mCurChar]++; if (mCurAnims[mCurChar] >= mAnims.Count) { mCurAnims[mCurChar] = 0; } UpdateCAStatus(); } } else if (act.mAction.Equals(Program.MyActions.IncreaseInvertInterval)) { mInvertInterval += InvertIncrement; foreach (Character c in mCharacters) { c.AutoInvert(true, mInvertInterval); } UpdateInvertStatus(); } else if (act.mAction.Equals(Program.MyActions.DecreaseInvertInterval)) { mInvertInterval -= InvertIncrement; if (mInvertInterval < InvertIncrement) { mInvertInterval = InvertIncrement; } foreach (Character c in mCharacters) { c.AutoInvert(true, mInvertInterval); } UpdateInvertStatus(); } else if (act.mAction.Equals(Program.MyActions.RandRotateStatic)) { if (mMeshes.Count > 0) { //make a random rotation mMeshRotations[mCurStatic] = new Vector3( Mathery.RandomFloatNext(mRand, 0, MathUtil.TwoPi), Mathery.RandomFloatNext(mRand, 0, MathUtil.TwoPi), Mathery.RandomFloatNext(mRand, 0, MathUtil.TwoPi)); UpdateStaticTransform(mCurStatic); } } else if (act.mAction.Equals(Program.MyActions.RandScaleStatic)) { if (mMeshes.Count > 0) { //make a random scale mMeshScales[mCurStatic] = new Vector3( Mathery.RandomFloatNext(mRand, 0.25f, 5f), Mathery.RandomFloatNext(mRand, 0.25f, 5f), Mathery.RandomFloatNext(mRand, 0.25f, 5f)); UpdateStaticTransform(mCurStatic); } } } mPartHit = null; mMeshHit = null; float bestDist = float.MaxValue; for (int i = 0; i < mMeshes.Count; i++) { StaticMesh sm = mMeshes[i]; float?bHit = sm.RayIntersect(startPos, endPos, true); if (bHit != null) { Mesh partHit = null; bHit = sm.RayIntersect(startPos, endPos, true, out partHit); if (bHit != null) { if (bHit.Value < bestDist) { bestDist = bHit.Value; mPartHit = partHit; mMeshHit = sm; } } } } if (mStaticMats != null) { mStaticMats.UpdateWVP(Matrix.Identity, mGD.GCam.View, mGD.GCam.Projection, mGD.GCam.Position); } if (mCharMats != null) { mCharMats.UpdateWVP(Matrix.Identity, mGD.GCam.View, mGD.GCam.Projection, mGD.GCam.Position); } mCPrims.Update(mGD.GCam, Vector3.Down); for (int i = 0; i < mCharacters.Count; i++) { Character c = mCharacters[i]; float? bHit = c.RayIntersect(startPos, endPos); if (bHit != null) { c.RayIntersectBones(startPos, endPos, false, out mCBone[i]); } else { mCBone[i] = 0; } } if (mFrameCheck == 10) { mFrameCheck = 0; UpdateThreadStatus(); } UpdatePosStatus(); UpdateHitStatus(); //this has to behind any text changes //otherwise the offsets will be messed up mST.Update(mGD.DC); mSUI.Update(mGD.DC); }
//if running on a fixed timestep, this might be called //more often with a smaller delta time than RenderUpdate() internal void Update(UpdateTimer time, List <Input.InputAction> actions, PlayerSteering ps) { //Thread.Sleep(30); float secDelta = time.GetUpdateDeltaSeconds(); mZone.ClearPushableVelocities(secDelta); //update model movers foreach (Component c in mBModelMovers) { c.Update(time); } Vector3 pos = Vector3.Zero; bool bGroundMove = false; UInt32 contents = mPCamMob.GetWorldContents(); if (mbFly) { pos = UpdateFly(secDelta, actions, ps); } else if (Misc.bFlagSet(contents, (UInt32)GameContents.Lava) || Misc.bFlagSet(contents, (UInt32)GameContents.Water) || Misc.bFlagSet(contents, (UInt32)GameContents.Slime)) { pos = UpdateSwimming(secDelta, actions, ps); } else { pos = UpdateGround(secDelta, actions, ps, out bGroundMove); //flip ground move as it returns as a jump bool bGroundMove = !bGroundMove; } UpdateMiscKeys(actions, ps); UpdateDynamicLights(actions); Vector3 camPos = Vector3.Zero; Vector3 endPos = pos; float msDelta = time.GetUpdateDeltaMilliSeconds(); mPCamMob.Move(endPos, msDelta, false, mbFly, bGroundMove, true, out endPos, out camPos); //check resulting move against triggers / pickups if (!mbFly) { foreach (Trigger t in mTriggers) { t.BoxTriggerCheck(mPCamMob, mPCamMob.GetBounds(), pos, endPos, msDelta); } foreach (ConvexVolume cv in mPickUpCVs) { if (!cv.Active) { continue; } if (cv.SphereMotionIntersects(PlayerBoxWidth, pos, endPos)) { PickUpThing(cv); cv.StateChange(ConvexVolume.State.Active, 0); } } } //check a slightly expanded box to see if any interactives are being touched mModelsHit.Clear(); if (!mbFly) { if (mZone.TraceStaticBoxVsModels(mFatBox, endPos, mModelsHit)) { //do stuff foreach (int model in mModelsHit) { foreach (BModelMover bmm in mBModelMovers) { if (bmm.GetModelIndex() == model) { bmm.StateChange(BModelMover.States.Forward, 1); bmm.StateChange(BModelMover.States.Moving, 1); } } } } } mGD.GCam.Update(camPos, ps.Pitch, ps.Yaw, ps.Roll); if (!mbFly) { if (mPCamMob.IsOnGround()) { //kill downward velocity so previous //falling momentum doesn't contribute to //a new jump if (mCamVelocity.Y < 0f) { mCamVelocity.Y = 0f; } } if (mPCamMob.IsBadFooting()) { //reduce downward velocity to avoid //getting stuck in V shaped floors if (mCamVelocity.Y < 0f) { mCamVelocity.Y -= (StumbleFriction * mCamVelocity.Y * secDelta); } } } //update pickup entities foreach (PickUp pu in mPickUps) { pu.Update(time); StaticMeshComp smc = pu.GetSMC(); if (smc == null) { continue; } StaticMesh sm = smc.mDrawObject as StaticMesh; if (sm == null) { continue; } float yaw = pu.GetYaw(); Matrix mat = smc.mPO.GetMatrix(); if (pu.mSpinningPart == -1) { smc.mPO.SetYaw(yaw); sm.SetTransform(mat); } else { sm.SetTransform(mat); sm.SetPartTransform(pu.mSpinningPart, Matrix.RotationY(yaw) * mat); } } mPB.Update(mGD.DC, time.GetUpdateDeltaMilliSeconds()); mAudio.Update(mGD.GCam); mST.ModifyStringText(mFonts[0], "ModelOn: " + mPCamMob.GetModelOn() + " : " + (int)mGD.GCam.Position.X + ", " + (int)mGD.GCam.Position.Y + ", " + (int)mGD.GCam.Position.Z + " (F)lyMode: " + mbFly + (mPCamMob.IsBadFooting()? " BadFooting!" : "") + " ModelsHit: " + mModelsHit.Count, "PosStatus"); mST.Update(mGD.DC); }
//if running on a fixed timestep, this might be called //more often with a smaller delta time than RenderUpdate() internal void Update(UpdateTimer time, List <Input.InputAction> actions, PlayerSteering ps) { //Thread.Sleep(30); mZone.ClearPushableVelocities(time.GetUpdateDeltaSeconds()); Vector3 impactPos = Vector3.Zero; if (mbPicking) { System.Drawing.Point cPos = System.Windows.Forms.Cursor.Position; cPos = mGD.RendForm.PointToClient(cPos); Vector2 cursVec = Vector2.UnitX * cPos.X; cursVec += Vector2.UnitY * cPos.Y; int modelOn; impactPos = mZone.TraceScreenPointRay(mGD.GCam, mGD.GetScreenViewPort(), cursVec, 1000f, out modelOn); var clicked = (from act in actions where act.mAction.Equals(Program.MyActions.MouseSelect) select act).FirstOrDefault(); if (clicked != null) { int node, numCons; List <int> conTo = new List <int>(); bool bInfo = mGraph.GetInfoAboutLocation(impactPos, mZone.FindWorldNodeLandedIn, out numCons, out node, conTo); if (bInfo) { switch (mPickTarget) { case PickTarget.A: Misc.SafeInvoke(ePickedA, node, new Vector3EventArgs(impactPos)); break; case PickTarget.B: Misc.SafeInvoke(ePickedB, node, new Vector3EventArgs(impactPos)); break; case PickTarget.Blocked: mGraph.SetPathConnectionPassable(impactPos, mZone.FindWorldNodeLandedIn, false); mPathDraw.BuildDrawInfo(mGraph); break; case PickTarget.UnBlocked: mGraph.SetPathConnectionPassable(impactPos, mZone.FindWorldNodeLandedIn, true); mPathDraw.BuildDrawInfo(mGraph); break; } mbPicking = false; mST.ModifyStringText(mFonts[0], "Picked point: " + impactPos.IntStr(), "PathStatus"); } } else { if (mbPicking) { mST.ModifyStringText(mFonts[0], "Picking point: " + impactPos.IntStr(), "PathStatus"); } } } float yawAmount = 0f; float pitchAmount = 0f; foreach (Input.InputAction act in actions) { if (act.mAction.Equals(Program.MyActions.NextLevel)) { mCurLevel++; if (mCurLevel >= mLevels.Count) { mCurLevel = 0; } ChangeLevel(mLevels[mCurLevel]); mST.ModifyStringText(mFonts[0], "(L) CurLevel: " + mLevels[mCurLevel], "LevelStatus"); } else if (act.mAction.Equals(Program.MyActions.Turn)) { yawAmount = act.mMultiplier; } else if (act.mAction.Equals(Program.MyActions.Pitch)) { pitchAmount = act.mMultiplier; } } Vector3 startPos = mCamMob.GetGroundPos(); Vector3 moveVec = ps.Update(startPos, mGD.GCam.Forward, mGD.GCam.Left, mGD.GCam.Up, actions); moveVec *= FlySpeed; Vector3 camPos = Vector3.Zero; Vector3 endPos = mCamMob.GetGroundPos() + moveVec * 100f; mCamMob.Move(endPos, time.GetUpdateDeltaMilliSeconds(), false, mbFly, true, true, out endPos, out camPos); mGD.GCam.Update(camPos, ps.Pitch, ps.Yaw, ps.Roll); mST.ModifyStringText(mFonts[0], "Position: " + " : " + mGD.GCam.Position.IntStr(), "PosStatus"); if (mGraph != null) { mGraph.Update(); } mST.Update(mGD.DC); }
static void Main() { Application.SetHighDpiMode(HighDpiMode.SystemAware); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); //turn this on for help with leaky stuff //Configuration.EnableObjectTracking =true; GraphicsDevice gd = new GraphicsDevice("BSP Light Explorer", FeatureLevel.Level_11_0, 0.1f, 3000f); //save renderform position gd.RendForm.DataBindings.Add(new System.Windows.Forms.Binding("Location", Settings.Default, "MainWindowPos", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); gd.RendForm.Location = Settings.Default.MainWindowPos; SharedForms.ShaderCompileHelper.mTitle = "Compiling Shaders..."; StuffKeeper sk = new StuffKeeper(); sk.eCompileNeeded += SharedForms.ShaderCompileHelper.CompileNeededHandler; sk.eCompileDone += SharedForms.ShaderCompileHelper.CompileDoneHandler; sk.Init(gd, "."); MatLib matLib = new MatLib(gd, sk); PlayerSteering pSteering = SetUpSteering(); Input inp = SetUpInput(); Random rand = new Random(); CommonPrims comPrims = new CommonPrims(gd, sk); bool bMouseLookOn = false; LightExplorer lex = new LightExplorer(gd, sk); EventHandler actHandler = new EventHandler( delegate(object s, EventArgs ea) { inp.ClearInputs(); }); EventHandler <EventArgs> deActHandler = new EventHandler <EventArgs>( delegate(object s, EventArgs ea) { gd.SetCapture(false); bMouseLookOn = false; }); gd.RendForm.Activated += actHandler; gd.RendForm.AppDeactivated += deActHandler; int resx = gd.RendForm.ClientRectangle.Width; int resy = gd.RendForm.ClientRectangle.Height; Vector3 pos = Vector3.One * 5f; Vector3 lightDir = -Vector3.UnitY; UpdateTimer time = new UpdateTimer(true, false); time.SetFixedTimeStepSeconds(1f / 60f); //60fps update rate time.SetMaxDeltaSeconds(MaxTimeDelta); List <Input.InputAction> acts = new List <Input.InputAction>(); RenderLoop.Run(gd.RendForm, () => { if (!gd.RendForm.Focused) { Thread.Sleep(33); } gd.CheckResize(); if (bMouseLookOn && gd.RendForm.Focused) { gd.ResetCursorPos(); } //Clear views gd.ClearViews(); time.Stamp(); while (time.GetUpdateDeltaSeconds() > 0f) { acts = UpdateInput(inp, gd, time.GetUpdateDeltaSeconds(), ref bMouseLookOn); if (!gd.RendForm.Focused) { acts.Clear(); bMouseLookOn = false; gd.SetCapture(false); inp.UnMapAxisAction(Input.MoveAxis.MouseYAxis); inp.UnMapAxisAction(Input.MoveAxis.MouseXAxis); } //check for speediness //psteering only allows speedy ground sprinting bool bFast = false; for (int i = 0; i < acts.Count; i++) { if (acts[i].mAction.Equals(MyActions.MoveForwardFast)) { bFast = true; } } Vector3 deltaMove = pSteering.Update(pos, gd.GCam.Forward, gd.GCam.Left, gd.GCam.Up, acts); if (bFast) { deltaMove *= 400f; } else { deltaMove *= 200f; } pos -= deltaMove; ChangeLight(acts, ref lightDir); lex.UpdateActions(acts); time.UpdateDone(); } //light direction is backwards now for some strange reason matLib.SetParameterForAll("mLightDirection", -lightDir); gd.GCam.Update(pos, pSteering.Pitch, pSteering.Yaw, pSteering.Roll); matLib.UpdateWVP(Matrix.Identity, gd.GCam.View, gd.GCam.Projection, gd.GCam.Position); comPrims.Update(gd.GCam, lightDir); lex.Update(time.GetUpdateDeltaMilliSeconds(), gd); lex.Render(gd); gd.Present(); acts.Clear(); }, true); //true here is slow but needed for winforms events Settings.Default.Save(); gd.RendForm.Activated -= actHandler; gd.RendForm.AppDeactivated -= deActHandler; lex.FreeAll(); comPrims.FreeAll(); inp.FreeAll(); matLib.FreeAll(); sk.eCompileDone -= SharedForms.ShaderCompileHelper.CompileDoneHandler; sk.eCompileNeeded -= SharedForms.ShaderCompileHelper.CompileNeededHandler; sk.FreeAll(); //Release all resources gd.ReleaseAll(); // Application.Run(new Form1()); }