001package com.fs.starfarer.api.impl.combat.dweller;
002
003import java.awt.Color;
004
005import org.lwjgl.opengl.GL11;
006
007import com.fs.starfarer.api.graphics.SpriteAPI;
008import com.fs.starfarer.api.util.WarpingSpriteRendererUtil.MutatingValue;
009
010public class WarpingSpriteRendererUtilV2  {
011        
012        public static class WSVertex {
013                public MutatingValue theta;
014                public MutatingValue radius;
015                
016                public WSVertex() {
017                        //theta = new MutatingValue(-360f * ((float) Math.random() * 3f + 1f), 360f * ((float) Math.random() * 3f + 1f), 30f + 70f * (float) Math.random());
018                        theta = new MutatingValue(-360f * ((float) Math.random() * 30f + 1f), 360f * ((float) Math.random() * 30f + 1f), 30f + 70f * (float) Math.random());
019                        radius = new MutatingValue(0, 10f + 15f * (float) Math.random(), 3f + 7f * (float) Math.random());
020                }
021                
022                public void advance(float amount) {
023                        theta.advance(amount);
024                        radius.advance(amount);
025                }
026                
027                Object writeReplace() {
028                        theta.setMax((int)theta.getMax());
029                        theta.setMin((int)theta.getMin());
030                        theta.setRate((int)theta.getRate());
031                        theta.setValue((int)theta.getValue());
032                        
033                        radius.setMax((int)radius.getMax());
034                        radius.setMin((int)radius.getMin());
035                        radius.setRate((int)radius.getRate());
036                        radius.setValue((int)radius.getValue());
037                        return this;
038                }
039        }
040        
041        protected int verticesWide, verticesTall;
042        protected WSVertex [] [] vertices;
043        protected SpriteAPI sprite;
044        protected boolean mirror = false;
045        
046        public WarpingSpriteRendererUtilV2(SpriteAPI sprite, int verticesWide, int verticesTall, 
047                                                                float minWarpRadius, float maxWarpRadius, float warpRateMult) {
048                
049                this.sprite = sprite;
050                this.verticesWide = verticesWide;
051                this.verticesTall = verticesTall;
052                
053                vertices = new WSVertex[verticesWide][verticesTall];
054                for (int i = 0; i < verticesWide; i++) {
055                        for (int j = 0; j < verticesTall; j++) {
056                                vertices[i][j] = new WSVertex();
057                                
058                                vertices[i][j].radius.set(minWarpRadius, maxWarpRadius);
059                                vertices[i][j].radius.rate *= warpRateMult;
060                                vertices[i][j].theta.rate *= warpRateMult;
061                                
062                        }
063                }
064        }
065        
066        /**
067         * Only works once, if the original mult was 1f - original rate values are not retained.
068         * @param mult
069         */
070        public void setWarpRateMult(float mult) {
071                for (int i = 0; i < verticesWide; i++) {
072                        for (int j = 0; j < verticesTall; j++) {
073                                vertices[i][j].radius.rate *= mult;
074                                vertices[i][j].theta.rate *= mult;
075                        }
076                }
077        }
078        
079        public void advance(float amount) {
080                for (int i = 0; i < verticesWide; i++) {
081                        for (int j = 0; j < verticesTall; j++) {
082                                vertices[i][j].advance(amount);
083                        }
084                }
085        }
086        
087        public void renderAtCenter(float x, float y) { 
088                float w = sprite.getWidth();
089                float h = sprite.getHeight();
090                
091                x -= w/2f;
092                y -= h/2f;
093                
094                sprite.bindTexture();
095                GL11.glPushMatrix();
096                
097                Color color = sprite.getColor();
098                GL11.glColor4ub((byte) color.getRed(), (byte) color.getGreen(),
099                                                (byte) color.getBlue(), (byte)(color.getAlpha() * sprite.getAlphaMult()));
100                
101                // translate to the right location and prepare to draw
102                GL11.glTranslatef(x, y, 0);
103
104                float centerX = sprite.getCenterX();
105                float centerY = sprite.getCenterY();
106                float angle = sprite.getAngle();
107                // translate to center, rotate, translate back
108                if (centerX != -1 && centerY != -1) {
109                        GL11.glTranslatef(w / 2, h / 2, 0);
110                        GL11.glRotatef(angle, 0, 0, 1);
111                        GL11.glTranslatef(- centerX, - centerY, 0);
112                } else {
113                        GL11.glTranslatef(w / 2, h / 2, 0);
114                        GL11.glRotatef(angle, 0, 0, 1);
115                        GL11.glTranslatef(-w / 2, -h / 2, 0);
116                }
117                
118                int blendSrc = sprite.getBlendSrc();
119                int blendDest = sprite.getBlendDest();
120                GL11.glEnable(GL11.GL_TEXTURE_2D);
121                GL11.glEnable(GL11.GL_BLEND);
122                GL11.glBlendFunc(blendSrc, blendDest);
123                
124                float tw = sprite.getTextureWidth() - 0.001f;
125                float th = sprite.getTextureHeight() - 0.001f;
126                
127                float cw = w / (float) (verticesWide - 1);
128                float ch = h / (float) (verticesTall - 1);
129                float ctw = tw / (float) (verticesWide - 1);
130                float cth = th / (float) (verticesTall- 1);
131        
132                for (float i = 0; i < verticesWide - 1; i++) {
133                //for (float i = 5; i < 7; i++) {
134                        GL11.glBegin(GL11.GL_QUAD_STRIP);
135                        {
136                                for (float j = 0; j < verticesTall; j++) {
137                                        float x1 = cw * i;
138                                        float y1 = ch * j;
139                                        float x2 = cw * (i + 1f);
140                                        float y2 = ch * j;
141                                        
142                                        float tx1 = ctw * i;
143                                        float ty1 = cth * j;
144                                        float tx2 = ctw * (i + 1f);
145                                        float ty2 = cth * j;
146                                        
147                                        if (mirror) {
148                                                tx1 = tw - tx1;
149                                                tx2 = th - tx2;
150                                        }
151                                        
152                                        if (i != 0 && i != verticesWide - 1 && j != 0 && j != verticesTall - 1) {
153                                                float theta = (float) Math.toRadians(vertices[(int)i][(int)j].theta.getValue());
154                                                float radius = vertices[(int)i][(int)j].radius.getValue();
155                                                float sin = (float) Math.sin(theta);
156                                                float cos = (float) Math.cos(theta);
157                                                
158                                                x1 += cos * radius; 
159                                                y1 += sin * radius;
160                                                //System.out.println("Radius: " + radius);
161                                        }
162                                        
163                                        if (i + 1 != 0 && i + 1 != verticesWide - 1 && j != 0 && j != verticesTall - 1) {
164                                                float theta = (float) Math.toRadians(vertices[(int)i + 1][(int)j].theta.getValue());
165                                                float radius = vertices[(int)i + 1][(int)j].radius.getValue();
166                                                float sin = (float) Math.sin(theta);
167                                                float cos = (float) Math.cos(theta);
168                                                
169                                                x2 += cos * radius; 
170                                                y2 += sin * radius;
171                                                //System.out.println("Radius: " + radius);
172                                        }
173
174                                        GL11.glTexCoord2f(tx1, ty1);
175                                        GL11.glVertex2f(x1, y1);
176                                        
177                                        GL11.glTexCoord2f(tx2, ty2);
178                                        GL11.glVertex2f(x2, y2);
179                                }
180                        }
181                        GL11.glEnd();
182                        
183                }
184                
185                GL11.glPopMatrix();
186        }
187
188        public int getVerticesWide() {
189                return verticesWide;
190        }
191
192        public int getVerticesTall() {
193                return verticesTall;
194        }
195
196        public SpriteAPI getSprite() {
197                return sprite;
198        }
199
200        public boolean isMirror() {
201                return mirror;
202        }
203
204        public void setMirror(boolean mirror) {
205                this.mirror = mirror;
206        }
207        
208}
209
210
211
212
213
214
215
216
217
218
219
220
221
222