"We offer new support options and therefor the forums are now in read-only mode! Please check out our Support Center for more information." - Vuforia Engine Team

Issue with download and render 3D objects from cloud

Hi Team,  I am working on Vuforia Cloud Recognition sample with 3D model. Here I have create one marker on Vuforia database with meta data as below: {  "Texture": [    "https://docs.google.com/uc?authuser=0&id=0By0KWpXcp6hOTVJyenlYMFppZGM&export=download"  ],  "model": "https://docs.google.com/uc?authuser=0&id=0By0KWpXcp6hONHZwbUVqNHNCRnM&export=download"} Now I am able to Recognition my marker and meta data. And Based on Meta data, I am downloading my 3D object and Texture via “async” call. but after downloading all details, i am not able to render my 3D object of screen and when i again Recognition marker, i am able to render 3D object from my local which is previously downloaded but some time Texture is applied.  My code as below for render object: - (id)initWithFrame:(CGRect)frame  appSession:(SampleApplicationSession *) app viewController:(ViewController *) aViewController{    self = [super initWithFrame:frame];        if (self) {        vapp = app;        self.viewController = aViewController;                // Enable retina mode if available on this device        if (YES == [vapp isRetinaDisplay]) {            [self setContentScaleFactor:2.0f];        }                // Create the OpenGL ES context        context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];                // The EAGLContext must be set for each thread that wishes to use it.        // Set it the first time this method is called (on the main thread)        if (context != [EAGLContext currentContext]) {            [EAGLContext setCurrentContext:context];        }        self.scale = 2.0;        self.tranX = 0.0;        self.tranY = 0.0;        offTargetTrackingEnabled = NO;        [self initShaders];    }        return self;} - (void)renderFrameQCAR{    [self setFramebuffer];        // Clear colour and depth buffers    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);        // Render video background and retrieve tracking state    QCAR::State state = QCAR::Renderer::getInstance().begin();    QCAR::Renderer::getInstance().drawVideoBackground();        glEnable(GL_DEPTH_TEST);    // We must detect if background reflection is active and adjust the culling direction.    // If the reflection is active, this means the pose matrix has been reflected as well,    // therefore standard counter clockwise face culling will result in "inside out" models.    glEnable(GL_CULL_FACE);    glCullFace(GL_BACK);    if(QCAR::Renderer::getInstance().getVideoBackgroundConfig().mReflection == QCAR::VIDEO_BACKGROUND_REFLECTION_ON)        glFrontFace(GL_CW);  //Front camera    else        glFrontFace(GL_CCW);   //Back camera        for (int i = 0; i < state.getNumTrackableResults(); ++i)    {        //Load 3D Model        // Get the trackable        const QCAR::TrackableResult* result = state.getTrackableResult(i);//        const QCAR::Trackable& trackable = result->getTrackable();        QCAR::Matrix44F modelViewMatrix = QCAR::Tool::convertPose2GLMatrix(result->getPose());        // OpenGL 2        QCAR::Matrix44F modelViewProjection;        SampleApplicationUtils::translatePoseMatrix(self.tranX, -self.tranY, self.scale, &modelViewMatrix.data[0]);        //SampleApplicationUtils::rotatePoseMatrix(90, 0, 1, 0,&modelViewMatrix.data[0]);        SampleApplicationUtils::scalePoseMatrix(self.scale, self.scale, self.scale, &modelViewMatrix.data[0]);        SampleApplicationUtils::multiplyMatrix(&vapp.projectionMatrix.data[0], &modelViewMatrix.data[0], &modelViewProjection.data[0]);        glUseProgram(shaderProgramID);                glVertexAttribPointer(vertexHandle, 3, GL_FLOAT, GL_FALSE, 0, buildingModel.vertices);        glVertexAttribPointer(normalHandle, 3, GL_FLOAT, GL_FALSE, 0, buildingModel.normals);        glVertexAttribPointer(textureCoordHandle, 2, GL_FLOAT, GL_FALSE, 0, buildingModel.texCoords);                glEnableVertexAttribArray(vertexHandle);        glEnableVertexAttribArray(normalHandle);        glEnableVertexAttribArray(textureCoordHandle);        glActiveTexture(GL_TEXTURE0);        glBindTexture(GL_TEXTURE_2D, augmentationTexture[0].textureID);        glUniformMatrix4fv(mvpMatrixHandle, 1, GL_FALSE, (const GLfloat*)&modelViewProjection.data[0]);        glUniform1i(texSampler2DHandle, 0 /*GL_TEXTURE0*/);//        glDrawElements(GL_TRIANGLES, NUM_TEAPOT_OBJECT_INDEX, GL_UNSIGNED_SHORT, (const GLvoid*)teapotIndices);        glDrawArrays(GL_TRIANGLES, 0, (int)buildingModel.numVertices);        glDisableVertexAttribArray(vertexHandle);        glDisableVertexAttribArray(normalHandle);        glDisableVertexAttribArray(textureCoordHandle);        SampleApplicationUtils::checkGlError("EAGLView renderFrameQCAR");    }        glDisable(GL_DEPTH_TEST);    glDisable(GL_CULL_FACE);    QCAR::Renderer::getInstance().end();    [self presentFramebuffer];    if (state.getNumTrackableResults() > 0) {        // we have a trackable so we stop the finder if it was on        if ([viewController isVisualSearchOn]) {            [viewController toggleVisualSearch];        }    } else {        // we have a no trackable so we retsrat the finder if not already started        if (! [viewController isVisualSearchOn]) {            [viewController toggleVisualSearch];        }    }     } - (void) loadBuildingsModel:(NSString *)path {      buildingModel = [[SampleApplication3DModel alloc] initWithTxtResourcePath:path];      [buildingModel read];}  - (void) loadTexture:(NSString *)path{        NSArray *list = [Constant listOfItemsInFolder:path];    if (list.count > 0) {        //Remove Old Texture        for (int i = 0; i < kNumAugmentationTextures; ++i) {            augmentationTexture[i] = nil;        }                //Load New Texture        for (int i = 0; i < kNumAugmentationTextures && i < list.count; ++i)        {            NSString *imagepath = [NSString stringWithFormat:@"%@/%@",path,list[i]];            augmentationTexture[i] = [[Texture alloc] initWithImagePath:imagepath];            //augmentationTexture[i] = [[Texture alloc] initWithImageFile:@"TextureTeapotBlue.png"];        }                        // Generate the OpenGL ES texture and upload the texture data for use        // when rendering the augmentation        for (int i = 0; i < kNumAugmentationTextures; ++i) {            GLuint textureID;            glGenTextures(1, &textureID);            [augmentationTexture[i] setTextureID:textureID];            glBindTexture(GL_TEXTURE_2D, textureID);            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);//            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);//            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, [augmentationTexture[i] width], [augmentationTexture[i] height], 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)[augmentationTexture[i] pngData]);        }    }}  My Upload functions as below: - (void) onQCARUpdate: (QCAR::State *) state {        // Get the tracker manager:    QCAR::TrackerManager& trackerManager = QCAR::TrackerManager::getInstance();        // Get the image tracker:     QCAR::ObjectTracker* objectTracker = static_cast<QCAR::ObjectTracker*>(trackerManager.getTracker(QCAR::ObjectTracker::getClassType()));        // Get the target finder:    QCAR::TargetFinder* finder = objectTracker->getTargetFinder();        // Check if there are new results available:    const int statusCode = finder->updateSearchResults();    if (statusCode < 0)    {        // Show a message if we encountered an error:        NSLog(@"update search result failed:%d", statusCode);        if (statusCode == QCAR::TargetFinder::UPDATE_ERROR_NO_NETWORK_CONNECTION) {            [self showUIAlertFromErrorCode:statusCode];        }    }    else if (statusCode == QCAR::TargetFinder::UPDATE_RESULTS_AVAILABLE)    {            if (isDownloading == false)            {                // Iterate through the new results:                for (int i = 0; i < finder->getResultCount(); ++i)                {                    const QCAR::TargetSearchResult* result = finder->getResult(i);                    // Check if this target is suitable for tracking:                    if (result->getTrackingRating() > 0)                    {                        isDownloading = true;                        dispatch_async(dispatch_get_main_queue(), ^{                            [self showLoadingAnimation];                        });                                                                        //Get Meta Data from Result                        NSString *modelfolder = [NSString stringWithFormat:@"%s",result->getUniqueTargetId()];                        NSString *modelfile = [NSString stringWithFormat:@"%@/model.txt",modelfolder];                        NSString *texturefolder = [NSString stringWithFormat:@"%@/Texture",modelfolder];                                                if([Constant isFileExist:modelfolder])                        {                            dispatch_async(dispatch_get_main_queue(), ^{                                [self.eaglView loadBuildingsModel:[Constant GetPathForFileName:modelfile]];                                [self.eaglView loadTexture:[Constant GetPathForFileName:texturefolder]];                                [self loadModel:finder Result:result];                                isDownloading = false;                            });                        }                        else                        {                            //Stop Tracking New Result                            if ([self isVisualSearchOn]) {                                [self toggleVisualSearch];                            }                            [Constant CreateFolder:modelfolder];                            const char *metadata = result->getMetaData();                            NSString *jsonstr = [NSString stringWithUTF8String:metadata];                            NSLog(@"Meta Data: %@",jsonstr);                            NSData *data = [NSData dataWithBytes:jsonstr.UTF8String length:jsonstr.length];                            NSMutableDictionary *objJson = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];                            [self downloaditem:objJson[@"model"] Handler:^(NSData *data) {                                [Constant SaveFileInApp:modelfile File:data];                                NSArray *texturelist = objJson[@"Texture"];                                if([Constant isFileExist:texturefolder])                                {                                    [Constant DeleteFileFromApp:texturefolder];                                }                                [Constant CreateFolder:texturefolder];                                [self downloadTextures:texturelist Folder:texturefolder Index:0 Handler:^(void) {                                    dispatch_async(dispatch_get_main_queue(), ^{//                                        [self.eaglView loadBuildingsModel:[Constant GetPathForFileName:modelfile]];//                                        [self.eaglView loadTexture:[Constant GetPathForFileName:texturefolder]];//                                        [self loadModel:f1 Result:r1];                                        isDownloading = false;                                        [self hideLoadingAnimation];                                        //Start Search Again                                        if (![self isVisualSearchOn]) {                                            [self toggleVisualSearch];                                        }                                    });                                }];                            }];                        }                    }               }        }            }        } I think, Main issue is app crash because result is deallocated when we have downloaded object.Guys, Are you have any suggestion to solve that issue?  ThanksKamal Mittal