public void preRenderUpdate(float timeElapsed) { var mParams = missile.parameters as SSpaceMissileVisualParameters; bodyObj.Pos = missile.displayPosition; bodyObj.Orient(missile.visualDirection, missile.up); bool ejection = missile.state == SSpaceMissileVisualData.State.Ejection; float smokeFrequency = Interpolate.Lerp( mParams.smokeEmissionFrequencyMin, mParams.smokeEmissionFrequencyMax, missile.visualSmokeAmmount); float sizeMin = ejection ? mParams.ejectionSmokeSizeMin : mParams.flameSmokeSizeMin; float sizeMax = ejection ? mParams.ejectionSmokeSizeMax : mParams.flameSmokeSizeMax; float smokeSize = Interpolate.Lerp(sizeMin, sizeMax, (float)SSpaceMissilesVisualSimulation.rand.NextDouble()); //flameSmokeEmitter.velocity = -missile.velocity; flameSmokeEmitter.center = missile.jetPosition(); flameSmokeEmitter.up = -missile.visualDirection; flameSmokeEmitter.emissionInterval = 1f / smokeFrequency; flameSmokeEmitter.componentScale = new Vector3(smokeSize); flameSmokeEmitter.effectorMask = (ushort) (ejection ? ParticleEffectorMasks.EjectionSmoke : ParticleEffectorMasks.FlameToSmoke); var vel = missile.velocity.LengthFast; flameSmokeEmitter.velocityFromCenterMagnitudeMin = ejection ? -vel / 2f : (-vel / 8f); flameSmokeEmitter.velocityFromCenterMagnitudeMax = ejection ? vel / 2f : (vel / 5f); flameSmokeEmitter.life = ejection ? mParams.ejectionSmokeDuration : mParams.flameSmokeDuration; if (missile.state == SSpaceMissileData.State.FadingOut) { float fadeFactor = 1f - (missile.timeSinceLaunch - missile.fadeTime) / mParams.fadeDuration; var color = bodyObj.MainColor; color.A = fadeFactor; bodyObj.MainColor = color; flameSmokeEmitter.life = flameSmokeEmitter.lifeMax * fadeFactor; } #if MISSILE_DEBUG RectangleF clientRect = OpenTKHelper.GetClientRect(); var xy = OpenTKHelper.WorldToScreen( missile.displayPosition, ref debugRays.viewProjMat, ref clientRect); debugCountdown.Pos = new Vector3(xy.X, xy.Y, 0f); debugCountdown.Label = Math.Floor(missile.timeToHit).ToString(); //debugCountdown.Label = missile.losRate.ToString("G3") + " : " + missile.losRateRate.ToString("G3"); debugRays.renderState.visible = mParams.debuggingAid; debugCountdown.renderState.visible = mParams.debuggingAid; #endif }
public override void Render(SSRenderConfig renderConfig) { var rc = cameraScene3d.renderConfig; RectangleF clientRect = OpenTKHelper.GetClientRect(); var cameraPos = (cameraScene3d.ActiveCamera != null) ? cameraScene3d.ActiveCamera.Pos //: Vector3.Transform(-Vector3.UnitZ, rc.invCameraViewMatrix.Inverted()).Normalized(); : Vector3.Transform(Vector3.Zero, rc.invCameraViewMatrix.Inverted()).Normalized(); foreach (var updater in _spriteUpdaters) { updater.updateSprites(this.instanceData, ref clientRect, ref cameraPos, ref rc.invCameraViewMatrix, ref rc.projectionMatrix); } base.Render(renderConfig); }
public void preRenderUpdate(float timeElapsed) { bool visible = (targetObj != null); _outline.renderState.visible = visible; _labelBelow.renderState.visible = visible; _labelAbove.renderState.visible = visible; if (!visible) { return; } RectangleF clientRect = OpenTKHelper.GetClientRect(); var targetRc = _targetObj3dScene.renderConfig; Matrix4 targetViewProj = targetRc.invCameraViewMatrix * targetRc.projectionMatrix; // outline Quaternion viewRotOnly = targetRc.invCameraViewMatrix.ExtractRotation(); Quaternion viewRotInverted = viewRotOnly.Inverted(); Vector3 viewRight = Vector3.Transform(Vector3.UnitX, viewRotInverted).Normalized(); Vector3 viewUp = Vector3.Transform(Vector3.UnitY, viewRotInverted).Normalized(); Vector2 targetScreenPos = OpenTKHelper.WorldToScreen(targetObj.Pos, ref targetViewProj, ref clientRect); targetScreenPos.X = (float)Math.Round(targetScreenPos.X); // fixes off-by-one pixel jitter targetScreenPos.Y = (float)Math.Round(targetScreenPos.Y); // animate outline line stipple _outline.enableLineStipple = this.isSelected; if (_outline.enableLineStipple) { ushort stipplePattern = _outline.lineStipplePattern; _stippleTimeAccumulator += timeElapsed; while (_stippleTimeAccumulator >= stippleStepInterval) { ushort firstBit = (ushort)((uint)stipplePattern & 0x1); stipplePattern >>= 1; stipplePattern |= (ushort)((uint)firstBit << 15); _outline.lineStipplePattern = stipplePattern; _stippleTimeAccumulator -= stippleStepInterval; } } float outlineHalfWidth; float outlineHalfHeight; if (fixedSizeTargets) { outlineHalfWidth = outlineMinPixelSz; outlineHalfHeight = outlineMinPixelSz; } else { // assumes target is a convential SSObject without billboarding, match scale to screen, etc. var size = targetObj.worldBoundingSphereRadius; Vector3 targetRightMost = targetObj.Pos + viewRight * size; Vector3 targetTopMost = targetObj.Pos + viewUp * size; Vector2 screenRightMostPt = OpenTKHelper.WorldToScreen(targetRightMost, ref targetViewProj, ref clientRect); Vector2 screenTopMostPt = OpenTKHelper.WorldToScreen(targetTopMost, ref targetViewProj, ref clientRect); outlineHalfWidth = 2f * (screenRightMostPt.X - targetScreenPos.X); outlineHalfWidth = Math.Max(outlineHalfWidth, outlineMinPixelSz); outlineHalfHeight = 2f * (targetScreenPos.Y - screenTopMostPt.Y); outlineHalfHeight = Math.Max(outlineHalfHeight, outlineMinPixelSz); } Vector3 targetViewPos = Vector3.Transform(targetObj.Pos, targetRc.invCameraViewMatrix); _targetViewDepth = targetViewPos.Z; bool targetIsInFront = _targetViewDepth < 0f; float lineWidth = targetIsInFront ? outlineWidthWhenInFront : outlinelineWidthWhenBehind; bool above, below, left, right; if (targetIsInFront) { left = targetScreenPos.X + outlineHalfWidth < 0f; right = !left && targetScreenPos.X - outlineHalfWidth > clientRect.Width; above = targetScreenPos.Y + outlineHalfHeight < 0f; below = !above && targetScreenPos.Y + outlineHalfHeight > clientRect.Height; } else // target is behind { float halfScrWidth = clientRect.Width / 2f; float halfScrHeight = clientRect.Height / 2f; float quartScrWidth = halfScrWidth / 2f; float quartScrHeight = halfScrHeight / 2f; right = targetScreenPos.X < quartScrWidth; left = !right && targetScreenPos.X > halfScrWidth + quartScrWidth; below = targetScreenPos.Y < quartScrHeight; above = !below && targetScreenPos.Y > halfScrHeight + quartScrHeight; } int orientIdx = (above ? 1 : 0) + (below ? 2 : 0) + (left ? 4 : 0) + (right ? 8 : 0); bool inTheCenter = (orientIdx == 0); if (!inTheCenter) { outlineHalfWidth = outlineMinPixelSz; outlineHalfHeight = outlineMinPixelSz; if (left) { targetScreenPos.X = outlineHalfWidth; } else if (right) { targetScreenPos.X = clientRect.Width - outlineHalfWidth - lineWidth * 2f; } if (above) { targetScreenPos.Y = outlineHalfHeight + _labelAbove.getGdiSize.Height; } else if (below) { targetScreenPos.Y = clientRect.Height - outlineHalfHeight - _labelBelow.getGdiSize.Height; } } _outline.Mesh = inTheCenter ? (targetIsInFront ? hudRectLinesMesh : hudCircleMesh) : hudTriMesh; _outline.Scale = new Vector3(outlineHalfWidth, outlineHalfHeight, 1f); _outline.Orient(outlineOrients [orientIdx]); _outline.Pos = new Vector3(targetScreenPos.X, targetScreenPos.Y, +1f); // labels _labelBelow.Label = fetchTextBelow(targetObj); var labelBelowPos = targetScreenPos; if (left) { labelBelowPos.X = 0f; } else if (right) { labelBelowPos.X = clientRect.Width - _labelBelow.getGdiSize.Width - 10f; } else { labelBelowPos.X -= _labelBelow.getGdiSize.Width / 2f; } labelBelowPos.Y += outlineHalfHeight; if ((left || right) && !below) { labelBelowPos.Y += outlineHalfHeight; } _labelBelow.Pos = new Vector3(labelBelowPos.X, labelBelowPos.Y, 0f); _labelAbove.Label = fetchTextAbove(targetObj); var labelAbovePos = targetScreenPos; if (left) { labelAbovePos.X = 0f; } else if (right) { labelAbovePos.X = clientRect.Width - _labelAbove.getGdiSize.Width - 10f; } else { labelAbovePos.X -= _labelAbove.getGdiSize.Width / 2f; } if ((left || right) && !above) { labelAbovePos.Y -= outlineHalfHeight; } labelAbovePos.Y -= (outlineHalfHeight + _labelAbove.getGdiSize.Height); _labelAbove.Pos = new Vector3(labelAbovePos.X, labelAbovePos.Y, 0f); Color4 color = fetchColor(targetObj); _outline.MainColor = color; _labelBelow.MainColor = color; _labelAbove.MainColor = color; _outlineScreenRect = new Rectangle( (int)(targetScreenPos.X - outlineHalfWidth), (int)(targetScreenPos.Y - outlineHalfHeight), (int)(outlineHalfWidth * 2f), (int)(outlineHalfHeight * 2f) ); }