TextureHandle RenderSSGI(RenderGraph renderGraph, HDCamera hdCamera, TextureHandle depthPyramid, TextureHandle stencilBuffer, TextureHandle normalBuffer, TextureHandle motionVectorsBuffer, ShaderVariablesRaytracing shaderVariablesRayTracingCB, HDUtils.PackedMipChainInfo info) { // Grab the global illumination volume component GlobalIllumination giSettings = hdCamera.volumeStack.GetComponent <GlobalIllumination>(); using (new RenderGraphProfilingScope(renderGraph, ProfilingSampler.Get(HDProfileId.SSGIPass))) { // Trace the signal TraceOutput traceOutput = TraceSSGI(renderGraph, hdCamera, giSettings, depthPyramid, normalBuffer, motionVectorsBuffer); // Evaluate the history validity float historyValidity = EvaluateIndirectDiffuseHistoryValidityCombined(hdCamera, giSettings.fullResolutionSS, false); SSGIDenoiser ssgiDenoiser = GetSSGIDenoiser(); SSGIDenoiser.SSGIDenoiserOutput denoiserOutput = ssgiDenoiser.Denoise(renderGraph, hdCamera, depthPyramid, normalBuffer, motionVectorsBuffer, traceOutput.outputBuffer0, traceOutput.outputBuffer1, m_DepthBufferMipChainInfo, !giSettings.fullResolutionSS, historyValidity: historyValidity); // Propagate the history PropagateIndirectDiffuseHistoryValidityCombined(hdCamera, giSettings.fullResolutionSS, false); // Convert back the result to RGB space TextureHandle colorBuffer = ConvertSSGI(renderGraph, hdCamera, !giSettings.fullResolutionSS, depthPyramid, stencilBuffer, normalBuffer, denoiserOutput.outputBuffer0, denoiserOutput.outputBuffer1); // Upscale it if required // If this was a half resolution effect, we still have to upscale it if (!giSettings.fullResolutionSS) { colorBuffer = UpscaleSSGI(renderGraph, hdCamera, giSettings, info, depthPyramid, colorBuffer); } return(colorBuffer); } }
private void TraceHeader() { TraceOutput.AppendLine("*************************************"); TraceOutput.AppendLine("_numberOfColumnsInChartDataTable: " + _numberOfColumnsInChartDataTable); TraceOutput.AppendLine("_numberOfRowsInChartDataTable: " + _numberOfRowsInChartDataTable); TraceOutput.AppendLine("ChartData"); if (ChartDataTable == null) { TraceOutput.AppendLine("Null"); } else { foreach (var column in ChartDataTable.Columns) { TraceOutput.Append(column + " "); } TraceOutput.AppendLine(); foreach (DataRow row in ChartDataTable.Rows) { foreach (var item in row.ItemArray) { TraceOutput.Append(item + " "); } TraceOutput.AppendLine(); } } }
public void groundCheck() { Vector3 pos = camera.getMovement(); Vector3 checkPoint = new Vector3(pos.X, pos.Y, pos.Z - Config.q3movement_playerRadius - 0.25f); this.groundTrace = this.bsp.trace(pos, checkPoint, camera, Config.q3movement_playerRadius); if (this.groundTrace.fraction == 1.0f) { // falling camera.onGround = false; return; } if (camera.velocity.Z > 0f && Vector3.Dot(camera.velocity, this.groundTrace.plane.normal) > 10f) { // jumping camera.onGround = false; return; } if (this.groundTrace.plane.normal.Z < 0.7f) { // steep slope camera.onGround = false; return; } camera.onGround = true; }
/// <summary> /// Sets the output for tracing (thead safe). /// </summary> public static void SetTraceOutput(TraceOutput output) { lock (s_traceFileLock) { s_traceOutput = (int)output; } }
/// <summary> /// Sets the output for tracing (thead safe). /// </summary> public static void SetTraceOutput(TraceOutput output) { lock (traceFileLock_) { traceOutput_ = (int)output; } }
public TraceOutput TraceS(Vector3 inputStart, Vector3 inputEnd) { TraceOutput result = new TraceOutput(); //if (inputStart.Equals(Vector3.Zero) && inputEnd.Equals(Vector3.Zero)) //{ // result.IsPoint = true; //} //else //{ // result.extends = new Vector3( //} // walk through the BSP tree //CheckNode(0, 0f, 1f, inputStart, inputEnd, result); if (result.outputFraction == 1f) { // nothing blocked the trace result.outputEnd = inputEnd; } else { result.outputEnd.X = inputStart.X + result.outputFraction * (inputEnd.X - inputStart.X); result.outputEnd.Y = inputStart.Y + result.outputFraction * (inputEnd.Y - inputStart.Y); result.outputEnd.Z = inputStart.Z + result.outputFraction * (inputEnd.Z - inputStart.Z); } return result; }
/// <summary> /// This method simulates calls to process various items and is used to /// demonstrate the TraceAttribute's functionality. Infrequently, this /// method will throw exceptions, and at other times will supply additional /// trace output in the form of Warning and Verbose messages. /// </summary> /// <remarks> /// Note that even if this class remained unaware that the TraceOutput object /// was available through the call context, the TraceAttribute would still /// provide tracing functionality. /// </remarks> /// <param name="itemName">The name of the item to be processed</param> /// <param name="total">A "ref" parameter whose value is shown (before and after the call) in the trace output</param> /// <returns>A new string based on the item name and the wait time generated within the method</returns> internal string ProcessItem(string itemName, ref int total) { // Simulate a wait time for items to be processed between 10 ms and 2 seconds. int simulatedWaitTime = 10 * randomNumber.Next(1, 21); int options = randomNumber.Next(10); Thread.Sleep(simulatedWaitTime); if (options >= 9) { throw new ApplicationException(); } TraceOutput tracer = (TraceOutput)CallContext.GetData(TraceOutput.ContextName); if (options >= 6) { tracer.WriteLine(TraceLevel.Verbose, "This a verbose message"); } else if (options >= 4) { tracer.WriteLine(TraceLevel.Warning, "This is a warning message"); } // Update total to see it reflected in our trace output. total += simulatedWaitTime; // Return a value to be displayed in the trace output. return(string.Format("{0} processed with wait-time of {1} milliseconds", itemName, simulatedWaitTime)); }
public static void EnumerateFolders(List <Folder> folderList, Folder startFolder, bool includeHiddenFolders) { TraceOutput.TraceEvent(TraceEventType.Information, 0, $"Enumerating {startFolder.Folders.Count} folders in {startFolder.Name}"); if (!startFolder.HasSubfolders()) { TraceOutput.TraceEvent(TraceEventType.Verbose, 0, "No subfolders found in folder specified"); return; } foreach (Folder folder in startFolder.Folders) { if (folder.IsHidden() && !includeHiddenFolders) { continue; } folderList.Add(folder); TraceOutput.TraceEvent(TraceEventType.Information, 0, $"\t{folder.Name}"); if (folder.Folders.Count > 0) { EnumerateFolders(folderList, folder, includeHiddenFolders); } } }
public Q3Movement(SceneCamera camera, q3bsptree bsp) { this.bsp = bsp; this.groundTrace = null; this.camera = camera; }
TraceOutput TraceSSGI(RenderGraph renderGraph, HDCamera hdCamera, GlobalIllumination giSettings, TextureHandle depthPyramid, TextureHandle normalBuffer, TextureHandle motionVectorsBuffer) { using (var builder = renderGraph.AddRenderPass <TraceSSGIPassData>("Trace SSGI", out var passData, ProfilingSampler.Get(HDProfileId.SSGITrace))) { builder.EnableAsyncCompute(false); passData.parameters = PrepareSSGITraceParameters(hdCamera, giSettings); passData.depthTexture = builder.ReadTexture(depthPyramid); passData.normalBuffer = builder.ReadTexture(normalBuffer); if (!hdCamera.frameSettings.IsEnabled(FrameSettingsField.ObjectMotionVectors)) { passData.motionVectorsBuffer = builder.ReadTexture(renderGraph.defaultResources.blackTextureXR); } else { passData.motionVectorsBuffer = builder.ReadTexture(motionVectorsBuffer); } var colorPyramid = hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ColorBufferMipChain); passData.colorPyramid = colorPyramid != null?builder.ReadTexture(renderGraph.ImportTexture(colorPyramid)) : renderGraph.defaultResources.blackTextureXR; var historyDepth = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.Depth); passData.historyDepth = historyDepth != null?builder.ReadTexture(renderGraph.ImportTexture(historyDepth)) : renderGraph.defaultResources.blackTextureXR; passData.hitPointBuffer = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "SSGI Hit Point" }); passData.outputBuffer0 = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "SSGI Signal0" })); passData.outputBuffer1 = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "SSGI Signal1" })); builder.SetRenderFunc( (TraceSSGIPassData data, RenderGraphContext ctx) => { // We need to fill the structure that holds the various resources SSGITraceResources resources = new SSGITraceResources(); resources.depthTexture = data.depthTexture; resources.normalBuffer = data.normalBuffer; resources.motionVectorsBuffer = data.motionVectorsBuffer; resources.colorPyramid = data.colorPyramid; resources.historyDepth = data.historyDepth; resources.hitPointBuffer = data.hitPointBuffer; resources.outputBuffer0 = data.outputBuffer0; resources.outputBuffer1 = data.outputBuffer1; ExecuteSSGITrace(ctx.cmd, data.parameters, resources); }); TraceOutput traceOutput = new TraceOutput(); traceOutput.outputBuffer0 = passData.outputBuffer0; traceOutput.outputBuffer1 = passData.outputBuffer1; return(traceOutput); } }
public static bool IsHidden(this Folder folder) { bool b; if (folder.HasIMAPIProperty(IMAPIPropertyTags.PR_ATTR_HIDDEN) == 1) { b = true; } else { b = false; } TraceOutput.TraceEvent(TraceEventType.Verbose, 0, $"{folder.Name} is hidden: {b}"); return(b); }
public static bool HasSubfolders(this Folder folder) { bool b; if (folder.HasIMAPIProperty(IMAPIPropertyTags.PR_SUBFOLDERS) == 1) { b = true; } else { b = false; } TraceOutput.TraceEvent(TraceEventType.Verbose, 0, $"{folder.Name} has subfolders: {b}"); return(b); }
private static int HasIMAPIProperty(this Folder folder, string propertyTag) { try { bool hasProp = (bool)folder.PropertyAccessor.GetProperty(propertyTag); if (hasProp) { return(1); } else { return(0); } } catch (System.Exception e) { TraceOutput.TraceInformation(e.Message); return(-1); } }
internal LogBeforeAfterTestAttribute(TraceOutput output = TraceOutput.Stdout) => this.output = output;
private void LogTrace(string log) => TraceOutput?.Invoke(this, new LogEventArgs { Text = log });
TraceOutput TraceSSGI(RenderGraph renderGraph, HDCamera hdCamera, GlobalIllumination giSettings, TextureHandle depthPyramid, TextureHandle normalBuffer, TextureHandle stencilBuffer, TextureHandle motionVectorsBuffer) { using (var builder = renderGraph.AddRenderPass <TraceSSGIPassData>("Trace SSGI", out var passData, ProfilingSampler.Get(HDProfileId.SSGITrace))) { builder.EnableAsyncCompute(false); //if (true) { passData.texWidth = hdCamera.actualWidth; passData.texHeight = hdCamera.actualHeight; passData.halfScreenSize.Set(passData.texWidth * 0.5f, passData.texHeight * 0.5f, 2.0f / passData.texWidth, 2.0f / passData.texHeight); } /* * else * { * passData.texWidth = hdCamera.actualWidth / 2; * passData.texHeight = hdCamera.actualHeight / 2; * passData.halfScreenSize.Set(passData.texWidth, passData.texHeight, 1.0f / passData.texWidth, 1.0f / passData.texHeight); * } */ passData.viewCount = hdCamera.viewCount; // Set the generation parameters passData.nearClipPlane = hdCamera.camera.nearClipPlane; passData.farClipPlane = hdCamera.camera.farClipPlane; passData.fullResolutionSS = true; passData.thickness = giSettings.depthBufferThickness.value; passData.raySteps = giSettings.maxRaySteps; passData.frameIndex = RayTracingFrameIndex(hdCamera, 16); passData.colorPyramidUvScaleAndLimitPrevFrame = HDUtils.ComputeViewportScaleAndLimit(hdCamera.historyRTHandleProperties.previousViewportSize, hdCamera.historyRTHandleProperties.previousRenderTargetSize); // Grab the right kernel passData.ssGICS = asset.renderPipelineResources.shaders.screenSpaceGlobalIlluminationCS; passData.traceKernel = true ? m_TraceGlobalIlluminationKernel : m_TraceGlobalIlluminationHalfKernel; passData.projectKernel = true ? m_ReprojectGlobalIlluminationKernel : m_ReprojectGlobalIlluminationHalfKernel; BlueNoise blueNoise = GetBlueNoiseManager(); passData.ditheredTextureSet = blueNoise.DitheredTextureSet8SPP(); passData.shaderVariablesRayTracingCB = m_ShaderVariablesRayTracingCB; passData.offsetBuffer = m_DepthBufferMipChainInfo.GetOffsetBufferData(m_DepthPyramidMipLevelOffsetsBuffer); passData.depthTexture = builder.ReadTexture(depthPyramid); passData.normalBuffer = builder.ReadTexture(normalBuffer); passData.stencilBuffer = builder.ReadTexture(stencilBuffer); if (!hdCamera.frameSettings.IsEnabled(FrameSettingsField.ObjectMotionVectors)) { passData.motionVectorsBuffer = builder.ReadTexture(renderGraph.defaultResources.blackTextureXR); } else { passData.motionVectorsBuffer = builder.ReadTexture(motionVectorsBuffer); } // History buffers var colorPyramid = hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ColorBufferMipChain); passData.colorPyramid = colorPyramid != null?builder.ReadTexture(renderGraph.ImportTexture(colorPyramid)) : renderGraph.defaultResources.blackTextureXR; var historyDepth = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.Depth); passData.historyDepth = historyDepth != null?builder.ReadTexture(renderGraph.ImportTexture(historyDepth)) : renderGraph.defaultResources.blackTextureXR; // Temporary textures passData.hitPointBuffer = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16_SFloat, enableRandomWrite = true, name = "SSGI Hit Point" }); // Output textures passData.outputBuffer0 = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.B10G11R11_UFloatPack32, enableRandomWrite = true, name = "SSGI Color" })); passData.outputBuffer1 = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16_SFloat, enableRandomWrite = true, name = "SSGI Additional Data" })); builder.SetRenderFunc( (TraceSSGIPassData data, RenderGraphContext ctx) => { int ssgiTileSize = 8; int numTilesXHR = (data.texWidth + (ssgiTileSize - 1)) / ssgiTileSize; int numTilesYHR = (data.texHeight + (ssgiTileSize - 1)) / ssgiTileSize; // Inject all the input scalars float n = data.nearClipPlane; float f = data.farClipPlane; float thicknessScale = 1.0f / (1.0f + data.thickness); float thicknessBias = -n / (f - n) * (data.thickness * thicknessScale); ctx.cmd.SetComputeFloatParam(data.ssGICS, HDShaderIDs._RayMarchingThicknessScale, thicknessScale); ctx.cmd.SetComputeFloatParam(data.ssGICS, HDShaderIDs._RayMarchingThicknessBias, thicknessBias); ctx.cmd.SetComputeIntParam(data.ssGICS, HDShaderIDs._RayMarchingSteps, data.raySteps); ctx.cmd.SetComputeIntParam(data.ssGICS, HDShaderIDs._RayMarchingReflectSky, 1); ctx.cmd.SetComputeIntParam(data.ssGICS, HDShaderIDs._IndirectDiffuseFrameIndex, data.frameIndex); // Inject half screen size if required if (!data.fullResolutionSS) { ctx.cmd.SetComputeVectorParam(data.ssGICS, HDShaderIDs._HalfScreenSize, data.halfScreenSize); } // Inject the ray-tracing sampling data BlueNoise.BindDitheredTextureSet(ctx.cmd, data.ditheredTextureSet); // Inject all the input textures/buffers ctx.cmd.SetComputeTextureParam(data.ssGICS, data.traceKernel, HDShaderIDs._DepthTexture, data.depthTexture); ctx.cmd.SetComputeTextureParam(data.ssGICS, data.traceKernel, HDShaderIDs._NormalBufferTexture, data.normalBuffer); ctx.cmd.SetComputeTextureParam(data.ssGICS, data.traceKernel, HDShaderIDs._IndirectDiffuseHitPointTextureRW, data.hitPointBuffer); ctx.cmd.SetComputeBufferParam(data.ssGICS, data.traceKernel, HDShaderIDs._DepthPyramidMipLevelOffsets, data.offsetBuffer); // Do the ray marching ctx.cmd.DispatchCompute(data.ssGICS, data.traceKernel, numTilesXHR, numTilesYHR, data.viewCount); // Update global constant buffer. // This should probably be a shader specific uniform instead of reusing the global constant buffer one since it's the only one updated here. ConstantBuffer.PushGlobal(ctx.cmd, data.shaderVariablesRayTracingCB, HDShaderIDs._ShaderVariablesRaytracing); // Inject all the input scalars ctx.cmd.SetComputeVectorParam(data.ssGICS, HDShaderIDs._ColorPyramidUvScaleAndLimitPrevFrame, data.colorPyramidUvScaleAndLimitPrevFrame); ctx.cmd.SetComputeIntParam(data.ssGICS, HDShaderIDs._ObjectMotionStencilBit, (int)StencilUsage.ObjectMotionVector); // Bind all the input buffers ctx.cmd.SetComputeTextureParam(data.ssGICS, data.projectKernel, HDShaderIDs._DepthTexture, data.depthTexture); ctx.cmd.SetComputeTextureParam(data.ssGICS, data.projectKernel, HDShaderIDs._StencilTexture, data.stencilBuffer, 0, RenderTextureSubElement.Stencil); ctx.cmd.SetComputeTextureParam(data.ssGICS, data.projectKernel, HDShaderIDs._NormalBufferTexture, data.normalBuffer); ctx.cmd.SetComputeTextureParam(data.ssGICS, data.projectKernel, HDShaderIDs._CameraMotionVectorsTexture, data.motionVectorsBuffer); ctx.cmd.SetComputeTextureParam(data.ssGICS, data.projectKernel, HDShaderIDs._IndirectDiffuseHitPointTexture, data.hitPointBuffer); ctx.cmd.SetComputeTextureParam(data.ssGICS, data.projectKernel, HDShaderIDs._ColorPyramidTexture, data.colorPyramid); ctx.cmd.SetComputeTextureParam(data.ssGICS, data.projectKernel, HDShaderIDs._HistoryDepthTexture, data.historyDepth); ctx.cmd.SetComputeBufferParam(data.ssGICS, data.projectKernel, HDShaderIDs._DepthPyramidMipLevelOffsets, data.offsetBuffer); // Bind the output texture ctx.cmd.SetComputeTextureParam(data.ssGICS, data.projectKernel, HDShaderIDs._IndirectDiffuseTexture0RW, data.outputBuffer0); ctx.cmd.SetComputeTextureParam(data.ssGICS, data.projectKernel, HDShaderIDs._IndirectDiffuseTexture1RW, data.outputBuffer1); // Do the reprojection ctx.cmd.DispatchCompute(data.ssGICS, data.projectKernel, numTilesXHR, numTilesYHR, data.viewCount); }); TraceOutput traceOutput = new TraceOutput(); traceOutput.outputBuffer0 = passData.outputBuffer0; traceOutput.outputBuffer1 = passData.outputBuffer1; return(traceOutput); } }
private void OnMessage(object sender, MessageEventArgs e) { if (!e.IsText && !e.Data.IsValidJson()) { return; } var json = JToken.Parse(e.Data); if (json.IsAuthMessage()) { InfoOutput?.Invoke(this, new LogEventArgs { Text = $"Authorize message: {e.Data.ToPrettyJson()}" }); return; } if (json.IsResult()) { // Isn't an event, log and exit. DebugOutput?.Invoke(this, new LogEventArgs { Text = $"Result message: {e.Data.ToPrettyJson()}" }); return; } if (!json.IsEvent()) { // Isn't an event! And event's are what we're working with. WarnOutput?.Invoke(this, new LogEventArgs { Text = $"Unsupported message (not an 'event'): {e.Data.ToPrettyJson()}" }); return; } var entId = json.ExtractEntityId().ToLowerInvariant(); var matchedApps = _apps.FindApps(entId); if (matchedApps.Count == 0) { // No matched apps, log and exit. if (EncounteredEntityIdsWithoutSubscription.Add(entId)) { TraceOutput?.Invoke(this, new LogEventArgs { Text = $"First time encounter of message with an EntityId that we're not listening on: {entId}" }); } return; } // Found matched apps! Log and determine which type InfoOutput?.Invoke(this, new LogEventArgs { Text = e.Data.ToPrettyJson() }); var eventData = new EventData { EntityId = entId }; if (json.IsClickEvent()) { eventData.ClickData = new Click { ClickType = (string)json["event"]["data"]["click_type"] }; } if (json.IsStateChangeEvent()) { //entity_boolean doesn't have a "last_triggered" attribute. if (!entId.Contains("input_boolean.")) { if (!json.HasNewStateWithLastTriggered()) { return; // Irrelevant event, we need new states that has "last time triggered" otherwise it might be an event provoked by reloading Hass. Unsure about this. } } if (!json.IsTheMostRelevantStateChangeMessage()) { return; // Is most probably a 'duped' event, throw it away .. } if (!json.HasNewState()) { return; // Irrelevant event, we need new states only .. } var rawGraph = JsonConvert.DeserializeObject <HassEventRawModel>(e.Data); var stateChange = new StateChanged(); stateChange.NewState = [email protected]_state?.state; stateChange.OldState = [email protected]_state?.state; stateChange.Attributes = JsonConvert.DeserializeObject <Dictionary <string, object> >(([email protected]_state ?? [email protected]_state ?? new StateRaw()).attributes.ToString()); eventData.StateChangeData = stateChange; } foreach (var hassApp in matchedApps.Where(p => p.IsExecuting == false)) { hassApp.IsExecuting = true; hassApp .ExecuteAsync(eventData, e.Data) .ContinueWith(p => { // Only on exception: Raise event.. var ex = p.Exception?.InnerExceptions?.FirstOrDefault() ?? p.Exception; ErrorOutput?.Invoke(this, new LogEventArgs { Text = ex?.Message, Exception = ex }); }, TaskContinuationOptions.OnlyOnFaulted) .ContinueWith(p => { hassApp.IsExecuting = false; }, TaskContinuationOptions.None); } }
private void OnWebsocketLog(LogData data, string arg2) { TraceOutput?.Invoke(this, new LogEventArgs { Text = data.Message + " [arg2]" }); }
public bool slideMove(bool apply_gravity) { int bumpcount; int numbumps = 4; //List planes = []; List <Vector3> planes = new List <Vector3>(); Vector3 endVelocity = Vector3.Zero; if (apply_gravity) { endVelocity = camera.velocity; // vec3_set(this.velocity, endVelocity ); endVelocity.Z -= Config.q3movement_gravity * Config.q3movement_frameTime; camera.velocity.Z = (camera.velocity.Z + endVelocity.Z) * 0.5f; if (this.groundTrace != null && this.groundTrace.plane != null) { // slide along the ground plane camera.velocity = this.clipVelocity(camera.velocity, this.groundTrace.plane.normal); } } // never turn against the ground plane if (this.groundTrace != null && this.groundTrace.plane != null) { planes.Add(this.groundTrace.plane.normal); //planes.addLast(this.groundTrace.plane.normal); } // never turn against original velocity Vector3 v = new Vector3(camera.velocity); v.Normalize(); planes.Add(v); //planes.addLast(v); float time_left = Config.q3movement_frameTime; Vector3 end = Vector3.Zero; for (bumpcount = 0; bumpcount < numbumps; ++bumpcount) { Vector3 pos = camera.getMovement(); // calculate position we are trying to move to //end = vec3(pos.add(camera.velocity.scale(time_left))); //end = vec3(pos.clone().add(camera.velocity.clone().scale(time_left))); end = pos + (camera.velocity * time_left); // see if we can make it there TraceOutput trace = this.bsp.trace(pos, end, camera, Config.q3movement_playerRadius); if (trace.allSolid) { // entity is completely trapped in another solid camera.velocity.Z = 0.0f; // don't build up falling damage, but allow sideways acceleration return(true); } if (trace.fraction > 0) { // actually covered some distance //vec3_set(trace.endPos, this.position); camera.applyMovement(trace.endPos); } if (trace.fraction == 1) { break; // moved the entire distance } time_left -= time_left * trace.fraction; planes.Add(trace.plane.normal); //planes.addLast(vec3_set(vec3(trace.plane.normal))); // // modify velocity so it parallels all of the clip planes // Vector3[] planeNormals = planes.ToArray(); // find a plane that it enters for (int i = 0; i < planes.Count; ++i) { float into = Vector3.Dot(camera.velocity, planeNormals[i]); //float into = vec3_dot(vec3(camera.velocity), planes.ToArray()[i]); if (into >= 0.1f) { continue; } // move doesn't interact with the plane // slide along the plane Vector3 clipVelocity = this.clipVelocity(camera.velocity, planeNormals[i]); Vector3 endClipVelocity = this.clipVelocity(endVelocity, planeNormals[i]); // see if there is a second plane that the new move enters for (int j = 0; j < planeNormals.Length; j++) { if (j == i) { continue; } if (Vector3.Dot(clipVelocity, planeNormals[j]) >= 0.1f) { continue; } // move doesn't interact with the plane // try clipping the move to the plane clipVelocity = this.clipVelocity(clipVelocity, planeNormals[j]); endClipVelocity = this.clipVelocity(endClipVelocity, planeNormals[j]); // see if it goes back into the first clip plane if (Vector3.Dot(clipVelocity, planeNormals[i]) >= 0) { continue; } // slide the original velocity along the crease Vector3 direction = Vector3.Zero; direction = Vector3.Cross(planeNormals[i], planeNormals[j]); direction.Normalize(); float d = Vector3.Dot(direction, camera.velocity); clipVelocity = (direction * d); direction = Vector3.Cross(planeNormals[i], planeNormals[j]); direction.Normalize(); d = Vector3.Dot(direction, endVelocity); endClipVelocity = direction * d; // see if there is a third plane the the new move enters for (int k = 0; k < planeNormals.Length; ++k) { if (k == i || k == j) { continue; } if (Vector3.Dot(clipVelocity, planeNormals[k]) >= 0.1f) { continue; } // move doesn't interact with the plane // stop dead at a tripple plane interaction camera.velocity = Vector3.Zero; return(true); } } // if we have fixed all interactions, try another move camera.velocity = clipVelocity; // vec3_set( clipVelocity, this.velocity ); endVelocity = endClipVelocity; // vec3_set( endClipVelocity, endVelocity ); break; } } if (apply_gravity) { camera.velocity = endVelocity; // vec3_set( endVelocity, this.velocity ); } return(bumpcount != 0); }
public void stepSlideMove(bool apply_gravity) { Vector3 start_o = camera.getMovement(); Vector3 start_v = camera.velocity; if (this.slideMove(apply_gravity) == false) { return; // we got exactly where we wanted to go first try } Vector3 down = start_o; // var down = vec3_set(start_o, [0,0,0]); down.Y -= Config.q3movement_stepsize; TraceOutput trace = this.bsp.trace(start_o, down, camera, Config.q3movement_playerRadius); Vector3 up = camera.Up; //up = camera.Up; // never step up when you still have up velocity if (camera.velocity.Z > 0 && (trace.fraction == 1.0f || Vector3.Dot(trace.plane.normal, up) < 0.7f)) { return; } //var down_o = vec3.set(this.position, [0,0,0]); //var down_v = vec3.set(this.velocity, [0,0,0]); //start_o = vec3_set (up); up = start_o; // vec3_set(start_o, up); up.Z += Config.q3movement_stepsize; // test the player position if they were a stepheight higher trace = this.bsp.trace(start_o, up, camera, Config.q3movement_playerRadius); if (trace.allSolid) { return; } // can't step up float stepSize = trace.endPos.Z - start_o.Z; // try slidemove from this position camera.applyMovement(trace.endPos); // vec3_set(trace.endPos, this.position); camera.velocity = start_v; // vec3_set(start_v, this.velocity); this.slideMove(apply_gravity); // push down the final amount //this.position = vec3_set(down); down = camera.getMovement(); // vec3_set(this.position, down); down.Z -= stepSize; trace = this.bsp.trace(camera.getMovement(), down, camera, Config.q3movement_playerRadius); if (trace.allSolid == false) { //trace['endPos'] = vec3_set(this.position); camera.applyMovement(trace.endPos); // vec3_set(trace.endPos, this.position); } if (trace.fraction < 1.0f) { camera.velocity = this.clipVelocity(camera.velocity, trace.plane.normal); } }