Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
// TextureAtlasViewController.m
// Game Landscaper
//
// Created by Saro Bear on 6/4/14.
// Copyright (c) 2015 Bear Love Studio LLP. All rights reserved.
//
#import <Photos/PhotosTypes.h>
#import <Photos/PHImageManager.h>
#import <Photos/Photos.h>
#import "TextureAtlasController.h"
#import "TextureAtlasHeaderController.h"
#import "TextureAtlasCanvasController.h"
#import "AtlasExportViewController.h"
#import "AtlasPropertyController.h"
#import "AtlasAssetsController.h"
#import "AtlasUtilityController.h"
#import "TextureAtlasDelegate.h"
#import "LaerExternalController.h"
#import "Utilities.h"
#import "Global.h"
#import "BrowserAsset.h"
#import "BearActivityIndicator.h"
#import "LaerDataManager.h"
#import "LaerAssetCD+CoreDataClass.h"
#import "AssetEntityCD+CoreDataClass.h"
#import "LaerProductCD+CoreDataClass.h"
#import "ScaleVariantsCD+CoreDataClass.h"
#import "MemoryLoadingView.h"
#import "UIImage+Resize.h"
#import "MagickWand.h"
#import "AtlasCreator.h"
#define STORYBOARD_ID_CANVAS_CONTROLLER
@"texture_canvas_controller"
#define STORYBOARD_ID_EXPORT_CONTROLLER
@"atlas_export_controller"
@end
-(void)memoryAlert
{
UIAlertController *alertController = [UIAlertController
alertControllerWithTitle:@"Warning" message:@"Device resources are becomig
expensive which may cause the app to crash! Do you still want to continue ?"
preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:yesAction];
[alertController addAction:cacelAction];
[self presentViewController:alertController animated:YES completion:^ {
}];
}
-(void)layoutChildrens
{
if(!_canvasController) return;
[self updateTexture];
}
-(void)addGestures
{
if(!_canvasController) {
return;
}
-(void)cleanup
{
NSArray *gestures = [self.view gestureRecognizers];
if(_canvasController)
{
[_canvasController removeFromParentViewController];
[_canvasController didMoveToParentViewController:nil];
[_canvasController.view removeFromSuperview];
}
_canvasController = nil;
}
-(void)initialize
{
_canvasController = (TextureAtlasCanvasController*)[Utilities
getController:STORYBOARD_ID_CANVAS_CONTROLLER];
[_canvasController setDelegate:self];
[_canvasController.view setFrame:CGRectMake(0.0f, 0.0f, [_atlasCD.width
floatValue], [_atlasCD.height floatValue])];
[self addChildViewController:_canvasController];
[self addGestures];
}
-(NSUInteger)getMaxIndexId
{
LaerDataManager *dataManager = [LaerDataManager sharedInstance];
return [dataManager fetchMaxValue:NSStringFromClass([AssetEntityCD class])
predicate:[NSPredicate predicateWithFormat:@"product.productName = %@",
[self currentProductName]] property:@"indexId"];
}
-(void)addAsset:(NSString*)asset
{
LaerDataManager *dataManager = [LaerDataManager sharedInstance];
ssize_t trimX = 0;
ssize_t trimY = 0;
size_t trimW = 0;
size_t trimH = 0;
MagickWandGenesis();
MagickWand *wand = NewMagickWand();
DestroyPixelWand(color);
}
wand = DestroyMagickWand(wand);
MagickWandTerminus();
if(!assetCD)
{
assetCD = [NSEntityDescription
insertNewObjectForEntityForName:NSStringFromClass([LaerAssetCD class])
inManagedObjectContext:[dataManager getObjectContext]];
[assetCD setFileName:[asset lastPathComponent]];
[assetCD setWidth:[NSNumber numberWithFloat:width]];
[assetCD setHeight:[NSNumber numberWithFloat:height]];
[assetCD setTrimX:[NSNumber numberWithFloat:trimX]];
[assetCD setTrimY:[NSNumber numberWithFloat:trimY]];
[assetCD setTrimHeight:[NSNumber numberWithFloat:trimH]];
[assetCD setTrimWidth:[NSNumber numberWithFloat:trimW]];
[assetCD setProduct:productCD];
}
[assetEntity setAsset:assetCD];
[assetEntity setProduct:productCD];
-(void)startImportAssets
{
if(_isMemoryUp)
{
[self memoryAlert];
return;
}
if(_didQuit)
{
[_importAssets removeAllObjects];
_importAssets = nil;
[self updateTexture];
return;
}
[_importAssets removeLastObject];
[self addAsset:[newAsset
stringByReplacingOccurrencesOfString:LANDSCAPER_THUMB_ID withString:@""]];
[self updateTexture];
if([_importAssets count]) {
[self performSelector:@selector(startImportAssets) withObject:NULL
afterDelay:0.1f];
}
else
{
[_importAssets removeAllObjects];
_importAssets = nil;
}
}];
}
-(void)saveCameraAsset:(saveImage)isSuccess
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,
0), ^
{
NSString *thumbName = [_importAssets lastObject];
NSString *thumbLocation = [Utilities getCameraShotThumbLocation:[self
currentProductName] usingThumbName:thumbName];
NSString *origLocation = [thumbLocation
stringByReplacingOccurrencesOfString:LANDSCAPER_THUMB_ID withString:@""];
dispatch_sync(dispatch_get_main_queue(), ^
{
if([Utilities moveIntoImagesPath:[self currentProductName]
filePath:origLocation])
{
if([Utilities saveIntoImagesPath:[self currentProductName] fileName:
[NSString stringWithFormat:@"%@%@",LANDSCAPER_THUMB_ID,[origLocation
lastPathComponent]] file:thumbData])
{
[Utilities deleteFromCameraPath:[self currentProductName]
fileName:thumbName];
isSuccess(YES);
}
else {
isSuccess(NO);
}
}
else {
isSuccess(NO);
}
});
});
}
return dstImage;
}
-(void)saveBrowseAsset:(saveImage)isSuccess
{
BrowserAsset *asset = [_importAssets lastObject];
NSString *fileName = [asset fileName];
NSString *thumbPath = [Utilities getImageLocationPlaceHolder:[self
currentProductName] assetName:[NSString stringWithFormat:@"%@
%@",LANDSCAPER_THUMB_ID, fileName]];
//dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,
0), ^
//{
MagickWandGenesis();
MagickWand *wand = NewMagickWand();
MagickBooleanType status = MagickReadImageBlob(wand, [origData
bytes], [origData length]);
if(status == MagickTrue)
{
NSString *filePath = [Utilities getImageLocationPlaceHolder:[self
currentProductName] assetName:fileName];
status = MagickWriteImage(wand, [filePath UTF8String]);
if(status == MagickTrue)
{
CGSize targetSize = [Utilities
getAspectSize:CGSizeMake(MagickGetImageWidth(wand),
MagickGetImageHeight(wand)) andSize:CGSizeMake(THUMBNAIL_AREA(0),
THUMBNAIL_AREA(0))];
if(status == MagickTrue) {
status = MagickWriteImage(wand, [thumbPath UTF8String]);
}
}
}
wand = DestroyMagickWand(wand);
MagickWandTerminus();
// dispatch_sync(dispatch_get_main_queue(), ^ {
isSuccess(status);
//});
///});
}];
}
else
{
//
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,
0), ^
// {
MagickCoreGenesis("", MagickFalse);
imageInfo = DestroyImageInfo(imageInfo);
exceptionInfo = DestroyExceptionInfo(exceptionInfo);
MagickCoreTerminus();
if(status == MagickTrue)
{
BOOL success = NO;
if([asset albumType] == EXTERNAL_BROWSER_TYPE_ITUNES_IMPORT)
{
NSData *outData = [NSData dataWithContentsOfFile:[asset
filePath]];
success = [Utilities saveIntoImagesPath:[self currentProductName]
fileName:fileName file:outData];
}
else {
success = [Utilities moveIntoImagesPath:[self currentProductName]
filePath:[asset filePath]];
}
// dispatch_sync(dispatch_get_main_queue(), ^ {
isSuccess(success);
// });
}
else
{
// dispatch_sync(dispatch_get_main_queue(), ^ {
isSuccess(status);
//});
}
// });
}
}
-(void)saveAsset:(saveImage)isSuccess
{
id asset = [_importAssets lastObject];
-(CGFloat)getScaleFromTransform:(CGAffineTransform)transform {
return sqrt(transform.a * transform.a + transform.c * transform.c);
}
-(NSString*)getBasicOrder:(int)order
{
NSString *orderStr = @"fileName";
switch (order)
{
case ATLAS_BASIC_ALGORITHM_WIDTH:
orderStr = @"width";
break;
case ATLAS_BASIC_ALGORITHM_HEIGHT:
orderStr = @"height";
break;
case ATLAS_BASIC_ALGORITHM_DEPTH:
orderStr = @"depth";
default:
break;
}
return orderStr;
}
-(void)prepareTexture
{
NSPredicate *predicate = [NSPredicate
predicateWithFormat:@"product.productName = %@ AND isSelected = 1",
self.currentProductName];
if(![fileLocation caseInsensitiveCompare:@"nil"]) {
[_headerController enableExportIcons:NO];
}
else
{
if([usedAssets count]) {
[_headerController enableExportIcons:YES];
}
else {
[_headerController enableExportIcons:NO];
}
}
[self textureUpdated:fileLocation];
}];
}
-(void)trimImages
{
LaerDataManager *dataManager = [LaerDataManager sharedInstance];
NSPredicate *assetPredicate = [NSPredicate
predicateWithFormat:@"product.productName = %@ AND atlasEntry = YES",
[self currentProductName]];
if(![assets count]) {
return;
}
MagickWandGenesis();
MagickWand *wand = NewMagickWand();
ssize_t trimX = 0;
ssize_t trimY = 0;
size_t trimW = 0;
size_t trimH = 0;
if(status)
{
MagickGetImagePage(wand, &trimW, &trimH, &trimX, &trimY);
DestroyPixelWand(color);
}
}
wand = DestroyMagickWand(wand);
MagickWandTerminus();
[self updateTexture];
}
switch (screen)
{
case OPTION_ALBUM_SCREEN:
{
controller = [Utilities
getController:STORYBOARD_ID_BROWSE_CONTROLLER];
[(LaerExternalController*)controller
setBrowserType:EXTERNAL_BROWSER_TYPE_ALBUM_IMPORT];
}
break;
case OPTION_CAMERA_SCREEN:
{
controller = [Utilities
getController:STORYBOARD_ID_CAMERA_CONTROLLER];
}
break;
case OPTION_BROWSE_SCREEN:
{
controller = [Utilities
getController:STORYBOARD_ID_BROWSE_CONTROLLER];
[(LaerExternalController*)controller
setBrowserType:EXTERNAL_BROWSER_TYPE_ITUNES_IMPORT];
}
break;
case OPTION_DROPBOX_IMPORT_SCREEN:
{
controller = [Utilities
getController:STORYBOARD_ID_BROWSE_CONTROLLER];
[(LaerExternalController*)controller
setBrowserType:EXTERNAL_BROWSER_TYPE_DROPBOX_IMPORT];
}
break;
case OPTION_DROPBOX_EXPORT_SCREEN:
{
controller = [Utilities
getController:STORYBOARD_ID_BROWSE_CONTROLLER];
[(LaerExternalController*)controller
setBrowserType:EXTERNAL_BROWSER_TYPE_DROPBOX_EXPORT];
}
break;
default:
break;
}
if(controller)
{
[controller setTitle:[self currentProductName]];
[(LaerExternalController*)controller setDelegate:self];
}
return (LaerExternalController*)controller;
}
-(CGFloat)screenDelay:(NSInteger)screen
{
CGFloat delay = 0.0f;
switch (screen)
{
case OPTION_ALBUM_SCREEN:
delay = 0.1f;
break;
case OPTION_CAMERA_SCREEN:
delay = 0.3f;
break;
case OPTION_SHARE_SCREEN:
delay = 0.1f;
break;
case OPTION_BROWSE_SCREEN:
delay = 0.1f;
break;
default:
break;
}
return delay;
}
-(CGFloat)screenDuration:(NSInteger)screen
{
CGFloat duration = 1.0f;
return duration;
}
-(void)hideForNavigationPanels
{
if(_curScreen > 1) {
[self showScreen:_curScreen show:NO];
}
}
-(void)removeOldScreen {
[self showScreen:_curScreen show:NO];
}
-(void)showScreen:(NSInteger)screen show:(BOOL)show
{
if(show)
{
NSInteger prevScreen = _curScreen;
_curScreen = screen;
if(_externalController)
{
[_externalController.view removeFromSuperview];
[_externalController didMoveToParentViewController:nil];
[_externalController removeFromParentViewController];
_externalController = nil;
[_headerController screenDidHide:prevScreen];
}
if(IS_IPHONE)
{
frame.size.height = self.view.bounds.size.height * 1.2f;
// offsetY = -0.1f;
}
[controller.view setAlpha:0.7f];
[controller.view setFrame:frame];
[self addChildViewController:controller];
[controller willMoveToParentViewController:self];
[self.view insertSubview:controller.view
aboveSubview:_canvasController.view];
_externalController = (LaerExternalController*)controller;
[_headerController screenDidShow:screen];
}];
}
else
{
if(!_externalController) return;
[self shouldShowStatusBar:NO];
}
-(void)updateSettingsSize:(CGSize)size {
[(AtlasPropertyController*)_settingsController updateSettingsContentSize:size];
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self initialize];
}
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
}
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
if(_canvasController) {
[self layoutChildrens];
}
}
-(void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
NSPredicate *predicate = [NSPredicate
predicateWithFormat:@"product.productName = %@", [self
currentProductName]];
NSInteger count = [[LaerDataManager sharedInstance]
fetchCount:NSStringFromClass([LaerAssetCD class]) predicate:predicate];
if(!count)
{
predicate = [NSPredicate predicateWithFormat:@"productName = %@",
[self currentProductName]];
LaerProductCD *product = [[LaerDataManager sharedInstance]
fetchEntity:NSStringFromClass([LaerProductCD class]) withPredicate:predicate
andResultType:NSManagedObjectResultType];
if(product) {
[[LaerDataManager sharedInstance] deleteObject:product];
}
}
else
{
if(_atlasCD && [_atlasCD hasChanges]) {
[[LaerDataManager sharedInstance] save];
}
}
if(_importAssets) {
[_importAssets removeAllObjects];
}
_importAssets = nil;
_didQuit = YES;
[self cleanup];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
_isMemoryUp = YES;
}
-(void)dealloc
{
_headerController = nil;
_atlasCD = nil;
}
-(BOOL)isExportPossible {
return [_headerController isExportPossible];
}
-(void)importedAssets:(NSArray *)assets
{
if(![assets count])
return;
if(!_importAssets) {
_importAssets = [NSMutableArray arrayWithArray:assets];
}
else
{
[_importAssets addObjectsFromArray:assets];
isFresh = NO;
}
assets = nil;
if(isFresh)
{
[_bearActInd startAnimation];
[self performSelector:@selector(startImportAssets) withObject:nil
afterDelay:1.0f];
}
}
-(void)updateTexture
{
[_bearActInd startAnimation];
[self performSelector:@selector(prepareTexture) withObject:nil
afterDelay:0.01f];
}
-(void)textureUpdated:(NSString*)fileLocation
{
[_utilitiesController updateMemoryWithCanvasSize:[[_canvasController view]
bounds].size andUnusedSprites:[_assetsController getUnusedAssetsCount]
fileLocation:fileLocation];
if(!_importAssets) {
[_bearActInd stopAnimation];
}
}
-(void)gotoMainMenu
{
[self.view setUserInteractionEnabled:NO];
-(BOOL)autoRotation {
return [[_atlasCD rotation] boolValue];
}
-(BOOL)autoSize {
return [[_atlasCD autoSize] boolValue];
}
-(BOOL)trim {
return [[_atlasCD trim] boolValue];
}
-(double)trimOpacity {
return [[_atlasCD trimOpacity] doubleValue];
}
-(void)setAutoSize:(BOOL)enable
{
[_atlasCD setAutoSize:[NSNumber numberWithBool:enable]];
[self updateTexture];
}
-(void)setPowSize:(BOOL)enable
{
[_atlasCD setPow:[NSNumber numberWithBool:enable]];
[self updateTexture];
}
-(void)setAutoRotation:(BOOL)enable
{
[_atlasCD setRotation:[NSNumber numberWithBool:enable]];
[self updateTexture];
}
-(void)setSortOrder:(BOOL)asc
{
[_atlasCD setOrderBy:[NSNumber numberWithBool:asc]];
[self updateTexture];
}
-(void)setTrim:(BOOL)trim
{
[_atlasCD setTrim:[NSNumber numberWithBool:trim]];
-(void)setTrimOpacity:(NSInteger)trimOpacity
{
[_atlasCD setTrimOpacity:[NSNumber numberWithInteger:trimOpacity]];
-(void)switchSettingsVisible
{
if(!_settingsTrailCons) {
return;
}
} completion:^(BOOL finished) {
[_headerController highlightSettingsIcon:isVisible];
}];
}
-(void)switchAssetsVisible
{
if(!_assetsTrailCons) {
return;
}
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
[_headerController highlightAssetsIcon:isVisible];
}];
}
-(void)switchUtilityVisible
{
if(!_utilityTrailCons) {
return;
}
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
[_headerController highlightUtilityIcon:isVisible];
}];
}
-(void)hideNavigationPanels
{
[UIView animateWithDuration:0.1f delay:0.0f
options:UIViewAnimationOptionBeginFromCurrentState animations:^
{
_assetsTrailCons.constant = ASSETS_WINDOW_HIDDEN * -1;
_settingsTrailCons.constant = SETTINGS_WINDOW_HIDDEN * -1;
_utilityTrailCons.constant = UTILITY_WINDOW_HIDDEN * -1;
[self.view layoutIfNeeded];
} completion:^(BOOL finished)
{
[_headerController highlightAssetsIcon:NO];
[_headerController highlightSettingsIcon:NO];
[_headerController highlightUtilityIcon:NO];
}];
}
-(void)updateCanvasSize:(CGSize)canvasSize
{
_atlasCD.width = [NSNumber numberWithInt:canvasSize.width];
_atlasCD.height = [NSNumber numberWithInt:canvasSize.height];
[self updateTexture];
}
-(void)algorithm:(int)index {
_atlasCD.algorithm = [NSNumber numberWithInt:index];
}
-(void)heuristics:(int)index
{
_atlasCD.heuristics = [NSNumber numberWithInt:index];
[self updateTexture];
}
-(void)dataFormat:(int)index {
_atlasCD.dataFormat = [NSNumber numberWithInt:index];
}
-(void)textureFormat:(int)index
{
_atlasCD.texFormat = [NSNumber numberWithInt:index];
[self updateTexture];
}
-(void)pixelFormat:(int)index
{
_atlasCD.pixelFormat = [NSNumber numberWithInt:index];
[self updateTexture];
}
-(int)currentAlgorithm {
return [_atlasCD.algorithm intValue];
}
-(int)currentHeuristic {
return [_atlasCD.heuristics intValue];
}
-(int)currentTexFormat {
return [_atlasCD.texFormat intValue];
}
-(int)currentDataFormat {
return [_atlasCD.dataFormat intValue];
}
-(int)currentPixelFormat {
return [_atlasCD.pixelFormat intValue];
}
-(CGSize)canvasSize {
return CGSizeMake([_atlasCD.width floatValue], [_atlasCD.height floatValue]);
}
-(void)exportAssets {
[self exportAtlas:EXPORT_OPTION_ITUNES];
}
-(void)exportAtlas:(NSInteger)option
{
AtlasExportViewController *exportController = (AtlasExportViewController*)
[Utilities getController:STORYBOARD_ID_EXPORT_CONTROLLER];
[exportController setTitle:[self currentProductName]];
[exportController setDelegate:self];
[exportController setExportOption:option];
[self addChildViewController:exportController];
[exportController didMoveToParentViewController:self];
[exportController.view setBounds:[self.view bounds]];
[self.view addSubview:exportController.view];
}
return YES;
}
-(void)panGestureHandler:(UIPanGestureRecognizer*)gesture
{
CGPoint translation = [gesture translationInView:self.view];
_canvasController.view.center = CGPointMake(_canvasController.view.center.x
+ translation.x, _canvasController.view.center.y + translation.y);
[gesture setTranslation:CGPointMake(0, 0) inView:self.view];
}
-(void)pinchGestureHandler:(UIPinchGestureRecognizer*)gesture
{
if(!_canvasController) {
return;
}
locationInView.x *= scale;
locationInView.y *= scale;
canvasView.layer.anchorPoint = CGPointMake(locationInView.x /
canvasView.frame.size.width, locationInView.y / canvasView.frame.size.height);
canvasView.center = locationInSuperview;
}
else
{
CGAffineTransform transform =
CGAffineTransformScale(canvasView.transform, gesture.scale, gesture.scale);
CGFloat scale = [self getScaleFromTransform:transform];
gesture.scale = 1.0f;
}
-(UIImage*)getTextureImage {
return [_canvasController getTextureImage];
}
@end