PDA

View Full Version : Timer update as I add objects



Winnssench
15th June 2020, 08:15
hello Everyone I am new to Qt, my project consists of reading data from csv file to make skeleton animation with spheres and for that I used Qtimer to add spheres at each timeout for the next line of data, for now it works but it saves the old spheres that I added at the previous timeout, I tried creating new QEntity but it didn't work, please help guys thank you in advance

ChrisW67
15th June 2020, 08:52
hello Everyone I am new to Qt, my project consists of reading data from csv file to make skeleton animation with spheres and for that I used Qtimer to add spheres at each timeout for the next line of data, for now it works but it saves the old spheres that I added at the previous timeout, I tried creating new QEntity but it didn't work, please help guys thank you in advance
You are going to have to show at least a pseudo-code description of what you are doing... but a compilable example of what you are doing would be better.

Winnssench
15th June 2020, 09:00
thank you for your reply,
here is the GitHub repo for my project
https://github.com/Winssench/SkReader.git
here is the function I call in the timer recursively


Qt3DCore::QEntity * MyTimer::myslot(QVector<SkeletonBuilder*> _CurrentBuilder)
{
SkeletonBuilder* Currento = _CurrentBuilder.first();

Qt3DCore::QEntity* test = new Qt3DCore::QEntity();
Currento->paintSkeleton(test);
test->setParent(_root);
CurrentBuilder.removeFirst();
return test;
}

the paintSkeleton fonction in the SkeletonBuilder class


Qt3DCore::QEntity * SkeletonBuilder::paintSkeleton( Qt3DCore::QEntity *ls)
{

QVector<Joint> skeletonBase = this->build();
Qt3DCore::QEntity *global= new Qt3DCore::QEntity(ls);

for(int i=0 ; i <skeletonBase.size() ; i++)
{
Qt3DCore::QEntity *sphereEntity = new Qt3DCore::QEntity(ls);
Qt3DExtras::QSphereMesh *sphereMesh = new Qt3DExtras::QSphereMesh;
sphereMesh->setRadius(0.3);
sphereMesh->setGenerateTangents(true);

Qt3DCore::QTransform *sphereTransform = new Qt3DCore::QTransform;
sphereTransform->setScale(0.98f);

//get the coordinates
Joint Currento = skeletonBase.at(i);
QString jointName = Currento.getName();
qDebug() <<Currento.getCoordinates() << Currento.getName()<< Qt::endl;
sphereTransform->setTranslation(Currento.getCoordinates()*10);
sphereTransform->setRotation(Currento.getQuaternion());

auto *materialSphere = new Qt3DExtras::QPhongMaterial(sphereMesh);
sphereEntity->addComponent(sphereMesh);
sphereEntity->addComponent(sphereTransform);
sphereEntity->addComponent(materialSphere);

}
return global;
}

and the main


int main(int argc, char* argv[])
{
QGuiApplication app(argc, argv);

Qt3DCore::QEntity* rootEntity = new Qt3DCore::QEntity ;

Qt3DExtras::Qt3DWindow* view = new Qt3DExtras::Qt3DWindow;;
QVector<QVector<Joint>> skeletonData= createScene();
QVector<SkeletonBuilder*> test;


for(int i = 0 ; i< 218; i++)
{
Qt3DCore::QEntity *tamp = new Qt3DCore::QEntity;
SkeletonBuilder* sb = new SkeletonBuilder(skeletonData,i,tamp);
test.append(sb);
}

MyTimer *myTimer = new MyTimer( new Qt3DCore::QEntity,test);

Qt3DRender::QCamera *camera = view->camera();
camera->lens()->setPerspectiveProjection(45.0f, 16.0f/9.0f, 0.1f, 1000.0f);
camera->setPosition(QVector3D(0, 0, 40.0f));
camera->setViewCenter(QVector3D(0, 0, 0));

// For camera controls
Qt3DExtras::QOrbitCameraController *camController = new Qt3DExtras::QOrbitCameraController(myTimer->getRoot());
camController->setLinearSpeed( 50.0f );
camController->setLookSpeed( 180.0f );
camController->setCamera(camera);


view->setRootEntity(myTimer->getRoot());

//view.hide();
view->show();

return app.exec();
}

hope this show bit the picture
13471

d_stranz
15th June 2020, 16:21
CurrentBuilder.removeFirst();

Is this your real code? The argument you pass in to MyTimer:: mySlot() is named "_CurrentBuilder", not "CurrentBuilder", so you are not modifying the same QVector as the one you passed as an argument.

Winnssench
15th June 2020, 19:12
Im sorry about the quality of the code, I was changing bit values its true it was first as you described but the animation doesn't start, it does only when I use the private CurrentBuilder but it saves the older spheres created
in the constructor I assign the _CurrentBuilder passed in the arguments to the private attribute of the class

d_stranz
15th June 2020, 21:21
You are also passing in the _CurrentBuilder QVector -by value-, which means it is making a copy of the argument you call it with. So the QVector you are modifying is the copy, not the original. If you want to avoid this, call it with QVector<> & _CurrentBuilder.

Winnssench
16th June 2020, 13:07
I fixed to use the reference instead of the copy but the problem persists, I think it is the way I show the spheres that causes the problem, each time it passes the QEntity(with all the spheres included) to the rootEntity
it draws them and then it adds another one while timeout is happening, but this logically would save the older spheres and this is what happens, if anyone has an idea how I can remove old QEntities from the rootEntity probably that would solve the issue

d_stranz
16th June 2020, 17:39
if anyone has an idea how I can remove old QEntities from the rootEntity probably that would solve the issue

I think you can just call deleteLater() on the entity pointer. From what I can read of the QNode / QEntity documentation, there are no explicit methods to remove child nodes, but since QNode inherits from QObject, it has the same behavior - simply delete the child and the QObject parent - child relationship takes care of the cleanup. Use deleteLater(), not delete() so that QObject can perform a proper cleanup (and so your program doesn't crash because the pointer has been deleted before Qt has cleaned up references to it).

If you are having a problem with identifying the spheres you want to delete, then you probably need to keep an extra data structure that stores them when you create them.