001 package com.croftsoft.core.animation.model.seri; 002 003 import java.awt.*; 004 import java.io.*; 005 import java.util.*; 006 007 import com.croftsoft.core.lang.NullArgumentException; 008 import com.croftsoft.core.math.geom.Point2DD; 009 import com.croftsoft.core.math.geom.PointXY; 010 import com.croftsoft.core.math.geom.ShapeLib; 011 import com.croftsoft.core.util.ArrayKeeper; 012 import com.croftsoft.core.util.ArrayLib; 013 import com.croftsoft.core.util.StableArrayKeeper; 014 015 import com.croftsoft.core.animation.model.Impassable; 016 import com.croftsoft.core.animation.model.Model; 017 import com.croftsoft.core.animation.model.ModelAccessor; 018 import com.croftsoft.core.animation.model.World; 019 020 /********************************************************************* 021 * A World implementation. 022 * 023 * @version 024 * 2003-06-18 025 * @since 026 * 2003-04-03 027 * @author 028 * <a href="https://www.croftsoft.com/">David Wallace Croft</a> 029 *********************************************************************/ 030 031 public class SeriWorld 032 implements World, Serializable 033 ////////////////////////////////////////////////////////////////////// 034 ////////////////////////////////////////////////////////////////////// 035 { 036 037 private static final long serialVersionUID = 0L; 038 039 // 040 041 protected final ArrayKeeper modelArrayKeeper; 042 043 // 044 045 private final Point2DD center; 046 047 private final java.util.List modelList; 048 049 // 050 051 private boolean cleared; 052 053 ////////////////////////////////////////////////////////////////////// 054 ////////////////////////////////////////////////////////////////////// 055 056 public SeriWorld ( ) 057 ////////////////////////////////////////////////////////////////////// 058 { 059 modelArrayKeeper = new StableArrayKeeper ( new Model [ 0 ] ); 060 061 center = new Point2DD ( ); 062 063 modelList = new ArrayList ( ); 064 } 065 066 ////////////////////////////////////////////////////////////////////// 067 ////////////////////////////////////////////////////////////////////// 068 069 public void clear ( ) 070 ////////////////////////////////////////////////////////////////////// 071 { 072 modelArrayKeeper.setArray ( new Model [ 0 ] ); 073 074 cleared = true; 075 } 076 077 public void remove ( Model model ) 078 ////////////////////////////////////////////////////////////////////// 079 { 080 modelArrayKeeper.remove ( model ); 081 } 082 083 ////////////////////////////////////////////////////////////////////// 084 ////////////////////////////////////////////////////////////////////// 085 086 public Impassable [ ] getImpassables ( ) 087 ////////////////////////////////////////////////////////////////////// 088 { 089 return ( Impassable [ ] ) 090 modelArrayKeeper.getArray ( Impassable.class ); 091 } 092 093 public Iterator getImpassables ( 094 Shape shape, 095 Model model ) 096 ////////////////////////////////////////////////////////////////////// 097 { 098 modelList.clear ( ); 099 100 Impassable [ ] impassables = getImpassables ( ); 101 102 for ( int i = 0; i < impassables.length; i++ ) 103 { 104 Impassable impassable = impassables [ i ]; 105 106 if ( ( impassable != model ) 107 && impassable.isActive ( ) 108 && ShapeLib.intersects ( shape, impassable.getShape ( ) ) ) 109 { 110 modelList.add ( impassable ); 111 } 112 } 113 114 return modelList.iterator ( ); 115 } 116 117 public Model [ ] getModels ( ) 118 ////////////////////////////////////////////////////////////////////// 119 { 120 return ( Model [ ] ) modelArrayKeeper.getArray ( ); 121 } 122 123 public ModelAccessor [ ] getModelAccessors ( 124 ModelAccessor [ ] modelAccessors ) 125 ////////////////////////////////////////////////////////////////////// 126 { 127 return getModelAccessors ( ( Shape ) null, modelAccessors ); 128 } 129 130 public ModelAccessor [ ] getModelAccessors ( 131 Shape shape, 132 ModelAccessor [ ] modelAccessors ) 133 ////////////////////////////////////////////////////////////////////// 134 { 135 Model [ ] allModels = getModels ( ); 136 137 if ( shape == null ) 138 { 139 return allModels; 140 } 141 142 NullArgumentException.check ( modelAccessors ); 143 144 int index = 0; 145 146 for ( int i = 0; i < allModels.length; i++ ) 147 { 148 Model model = allModels [ i ]; 149 150 if ( ShapeLib.intersects ( shape, model.getShape ( ) ) ) 151 { 152 if ( index < modelAccessors.length ) 153 { 154 modelAccessors [ index ] = model; 155 } 156 else 157 { 158 modelAccessors = ( ModelAccessor [ ] ) 159 ArrayLib.append ( modelAccessors, model ); 160 } 161 162 index++; 163 } 164 } 165 166 if ( index < modelAccessors.length ) 167 { 168 modelAccessors [ index ] = null; 169 } 170 171 return modelAccessors; 172 } 173 174 public boolean isBlocked ( 175 Shape shape, 176 Model model ) 177 ////////////////////////////////////////////////////////////////////// 178 { 179 Impassable [ ] impassables = getImpassables ( ); 180 181 for ( int i = 0; i < impassables.length; i++ ) 182 { 183 Impassable impassable = impassables [ i ]; 184 185 if ( ( impassable != model ) 186 && impassable.isActive ( ) 187 && ShapeLib.intersects ( shape, impassable.getShape ( ) ) ) 188 { 189 return true; 190 } 191 } 192 193 return false; 194 } 195 196 public boolean isBlocked ( Model model ) 197 ////////////////////////////////////////////////////////////////////// 198 { 199 return isBlocked ( model.getShape ( ), model ); 200 } 201 202 public Model getModel ( 203 PointXY pointXY, 204 Class [ ] classes, 205 Model model ) 206 ////////////////////////////////////////////////////////////////////// 207 { 208 double x = pointXY.getX ( ); 209 210 double y = pointXY.getY ( ); 211 212 Model [ ] models = getModels ( ); 213 214 for ( int i = 0; i < models.length; i++ ) 215 { 216 Model otherModel = models [ i ]; 217 218 if ( ( otherModel != model ) 219 && otherModel.isActive ( ) 220 && otherModel.getShape ( ).contains ( x, y ) ) 221 { 222 for ( int j = 0; j < classes.length; j++ ) 223 { 224 if ( classes [ j ].isInstance ( otherModel ) ) 225 { 226 return otherModel; 227 } 228 } 229 } 230 } 231 232 return null; 233 } 234 235 public Model [ ] getModels ( Class c ) 236 ////////////////////////////////////////////////////////////////////// 237 { 238 if ( c == null ) 239 { 240 return ( Model [ ] ) modelArrayKeeper.getArray ( ); 241 } 242 243 return ( Model [ ] ) modelArrayKeeper.getArray ( c ); 244 } 245 246 public Model [ ] getModels ( 247 PointXY pointXY, 248 Model [ ] models, 249 Class c ) 250 ////////////////////////////////////////////////////////////////////// 251 { 252 Model [ ] allModels = getModels ( c ); 253 254 if ( pointXY == null ) 255 { 256 return allModels; 257 } 258 259 NullArgumentException.check ( models ); 260 261 double x = pointXY.getX ( ); 262 263 double y = pointXY.getY ( ); 264 265 int index = 0; 266 267 for ( int i = 0; i < allModels.length; i++ ) 268 { 269 Model model = allModels [ i ]; 270 271 if ( model.isActive ( ) 272 && model.getShape ( ).contains ( x, y ) ) 273 { 274 if ( index < models.length ) 275 { 276 models [ index ] = model; 277 } 278 else 279 { 280 models = ( Model [ ] ) ArrayLib.append ( models, model ); 281 } 282 283 index++; 284 } 285 } 286 287 if ( index < models.length ) 288 { 289 models [ index ] = null; 290 } 291 292 return models; 293 } 294 295 public Model [ ] getModels ( 296 Shape shape, 297 Model [ ] models, 298 Class c ) 299 ////////////////////////////////////////////////////////////////////// 300 { 301 Model [ ] allModels = getModels ( c ); 302 303 if ( shape == null ) 304 { 305 return allModels; 306 } 307 308 NullArgumentException.check ( models ); 309 310 int index = 0; 311 312 for ( int i = 0; i < allModels.length; i++ ) 313 { 314 Model model = allModels [ i ]; 315 316 if ( model.isActive ( ) 317 && ShapeLib.intersects ( shape, model.getShape ( ) ) ) 318 { 319 if ( index < models.length ) 320 { 321 models [ index ] = model; 322 } 323 else 324 { 325 models = ( Model [ ] ) ArrayLib.append ( models, model ); 326 } 327 328 index++; 329 } 330 } 331 332 if ( index < models.length ) 333 { 334 models [ index ] = null; 335 } 336 337 return models; 338 } 339 340 public Model getModelClosest ( 341 PointXY pointXY, 342 Class c, 343 Model model ) 344 ////////////////////////////////////////////////////////////////////// 345 { 346 int index = -1; 347 348 double closestDistance = Double.POSITIVE_INFINITY; 349 350 Model [ ] models = ( Model [ ] ) modelArrayKeeper.getArray ( ); 351 352 for ( int i = 0; i < models.length; i++ ) 353 { 354 Model otherModel = models [ i ]; 355 356 if ( ( otherModel != model ) 357 && otherModel.isActive ( ) 358 && c.isInstance ( otherModel ) ) 359 { 360 double distance = ShapeLib.getCenter ( 361 otherModel.getShape ( ), center ).distanceXY ( pointXY ); 362 363 if ( distance < closestDistance ) 364 { 365 closestDistance = distance; 366 367 index = i; 368 } 369 } 370 } 371 372 if ( index > -1 ) 373 { 374 return models [ index ]; 375 } 376 377 return null; 378 } 379 380 ////////////////////////////////////////////////////////////////////// 381 // mutator methods 382 ////////////////////////////////////////////////////////////////////// 383 384 public boolean isCleared ( ) { return cleared; } 385 386 public void prepare ( ) 387 ////////////////////////////////////////////////////////////////////// 388 { 389 Model [ ] models = getModels ( ); 390 391 for ( int i = 0; i < models.length; i++ ) 392 { 393 models [ i ].prepare ( ); 394 } 395 396 cleared = false; 397 } 398 399 public void update ( double timeDelta ) 400 ////////////////////////////////////////////////////////////////////// 401 { 402 Model [ ] models = getModels ( ); 403 404 for ( int i = 0; i < models.length; i++ ) 405 { 406 models [ i ].update ( timeDelta ); 407 } 408 } 409 410 ////////////////////////////////////////////////////////////////////// 411 ////////////////////////////////////////////////////////////////////// 412 }