protected override void UpdateStates(int stateIndex1, int stateIndex2) { var state1 = Light.States[stateIndex1]; var state2 = Light.States[stateIndex2]; LightViewer.CalculateLightCone(state1, out Position1, out Direction1, out Angle1, out Radius1, out Distance1, out Color1); LightViewer.CalculateLightCone(state2, out Position2, out Direction2, out Angle2, out Radius2, out Distance2, out Color2); }
public LightConePrimitive(LightViewer lightViewer, RenderProcess renderProcess, Light light) : base(light) { Debug.Assert(light.Type == LightType.Cone, "LightConePrimitive is only for LightType.Cone lights."); if (VertexDeclaration == null) { VertexDeclaration = new VertexDeclaration(renderProcess.GraphicsDevice, LightConeVertex.VertexElements); } if (VertexBuffer == null) { var vertexData = new LightConeVertex[(CircleSegments + 2) * StateCount]; SetUpTransitions((state, stateIndex1, stateIndex2) => { var state1 = Light.States[stateIndex1]; var state2 = Light.States[stateIndex2]; #if DEBUG_LIGHT_TRANSITIONS Console.WriteLine(" Transition {0} is from state {1} to state {2} over {3:F1}s", state, stateIndex1, stateIndex2, state1.Duration); #endif Vector3 position1, position2, direction1, direction2; float angle1, angle2, radius1, radius2, distance1, distance2; Vector4 color1, color2; LightViewer.CalculateLightCone(state1, out position1, out direction1, out angle1, out radius1, out distance1, out color1); LightViewer.CalculateLightCone(state2, out position2, out direction2, out angle2, out radius2, out distance2, out color2); var direction1Right = Vector3.Cross(direction1, Vector3.UnitY); var direction1Up = Vector3.Cross(direction1Right, direction1); var direction2Right = Vector3.Cross(direction2, Vector3.UnitY); var direction2Up = Vector3.Cross(direction2Right, direction2); for (var i = 0; i < CircleSegments; i++) { var a1 = MathHelper.TwoPi * i / CircleSegments; var a2 = MathHelper.TwoPi * (i + 1) / CircleSegments; var v1 = position1 + direction1 * distance1 + direction1Right * (float)(radius1 * Math.Cos(a1)) + direction1Up * (float)(radius1 * Math.Sin(a1)); var v2 = position2 + direction2 * distance2 + direction2Right * (float)(radius2 * Math.Cos(a2)) + direction2Up * (float)(radius2 * Math.Sin(a2)); vertexData[(CircleSegments + 2) * state + i] = new LightConeVertex(v1, v2, color1, color2); } vertexData[(CircleSegments + 2) * state + CircleSegments + 0] = new LightConeVertex(position1, position2, color1, color2); vertexData[(CircleSegments + 2) * state + CircleSegments + 1] = new LightConeVertex(new Vector3(position1.X, position1.Y, position1.Z - distance1), new Vector3(position2.X, position2.Y, position2.Z - distance2), color1, color2); }); VertexBuffer = new VertexBuffer(renderProcess.GraphicsDevice, typeof(LightConeVertex), vertexData.Length, BufferUsage.WriteOnly); VertexBuffer.SetData(vertexData); } if (IndexBuffer == null) { var indexData = new short[6 * CircleSegments]; for (var i = 0; i < CircleSegments; i++) { var i2 = (i + 1) % CircleSegments; indexData[6 * i + 0] = (short)(CircleSegments + 0); indexData[6 * i + 1] = (short)i2; indexData[6 * i + 2] = (short)i; indexData[6 * i + 3] = (short)i; indexData[6 * i + 4] = (short)i2; indexData[6 * i + 5] = (short)(CircleSegments + 1); } IndexBuffer = new IndexBuffer(renderProcess.GraphicsDevice, typeof(short), indexData.Length, BufferUsage.WriteOnly); IndexBuffer.SetData(indexData); } UpdateState(lightViewer); }