Add locking mechanism to prevent updating transform/parent
This commit is contained in:
@@ -48,6 +48,8 @@ public:
|
|||||||
|
|
||||||
void updateTransform();
|
void updateTransform();
|
||||||
|
|
||||||
|
void lock();
|
||||||
|
|
||||||
void dumpMe(FILE *fp);
|
void dumpMe(FILE *fp);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ public:
|
|||||||
|
|
||||||
Group(const char *name = nullptr);
|
Group(const char *name = nullptr);
|
||||||
|
|
||||||
|
void lock();
|
||||||
|
|
||||||
const char *getName() { return this->name; };
|
const char *getName() { return this->name; };
|
||||||
|
|
||||||
void dumpMe(FILE * fp);
|
void dumpMe(FILE * fp);
|
||||||
|
|||||||
@@ -70,6 +70,8 @@ public:
|
|||||||
void updateBoundingBox();
|
void updateBoundingBox();
|
||||||
void updateTransform();
|
void updateTransform();
|
||||||
|
|
||||||
|
void lock();
|
||||||
|
|
||||||
void dumpMe(FILE * fp);
|
void dumpMe(FILE * fp);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
ShapeType type;
|
ShapeType type;
|
||||||
Matrix localTransformMatrix;
|
Matrix localTransformMatrix;
|
||||||
|
bool locked;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual Intersect localIntersect(Ray r) = 0;
|
virtual Intersect localIntersect(Ray r) = 0;
|
||||||
@@ -75,10 +76,20 @@ public:
|
|||||||
|
|
||||||
virtual void dumpMe(FILE *fp);
|
virtual void dumpMe(FILE *fp);
|
||||||
|
|
||||||
|
/* When an object is locked, the matrix transformation and bounding box can't be updated. This is
|
||||||
|
* usefull to move object between group without changing the real hierarchy between them.
|
||||||
|
* It will also not change the parent member.
|
||||||
|
* This is supposed to be used only before a render is going to start so we can optimise the
|
||||||
|
* way the object are stored to prefer lots of un-needed intersections.
|
||||||
|
*/
|
||||||
|
virtual void lock() { this->locked = true; };
|
||||||
|
|
||||||
Tuple worldToObject(Tuple point) { return this->inverseTransform * point; };
|
Tuple worldToObject(Tuple point) { return this->inverseTransform * point; };
|
||||||
Tuple objectToWorld(Tuple point) { return this->transformMatrix * point; };
|
Tuple objectToWorld(Tuple point) { return this->transformMatrix * point; };
|
||||||
Tuple normalToWorld(Tuple normalVector);
|
Tuple normalToWorld(Tuple normalVector);
|
||||||
|
|
||||||
|
void setParent(Shape *parent) { if (!this->locked) { this->parent = parent; };};
|
||||||
|
|
||||||
void setTransform(Matrix transform);
|
void setTransform(Matrix transform);
|
||||||
void setMaterial(Material material) { this->material = material; this->materialSet = true; };
|
void setMaterial(Material material) { this->material = material; this->materialSet = true; };
|
||||||
Ray transform(Ray r) { return Ray(this->transformMatrix * r.origin, this->transformMatrix * r.direction); };
|
Ray transform(Ray r) { return Ray(this->transformMatrix * r.origin, this->transformMatrix * r.direction); };
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ CSG::CSG(OperationType operation, Shape *left, Shape *right) : Shape(Shape::CSG)
|
|||||||
{
|
{
|
||||||
stats.addCsg();
|
stats.addCsg();
|
||||||
|
|
||||||
this->left->parent = this;
|
this->left->setParent(this);
|
||||||
this->right->parent = this;
|
this->right->setParent(this);
|
||||||
|
|
||||||
this->bounds | this->left->getBounds();
|
this->bounds | this->left->getBounds();
|
||||||
this->bounds | this->right->getBounds();
|
this->bounds | this->right->getBounds();
|
||||||
@@ -134,6 +134,19 @@ void CSG::filterIntersections(Intersect &xs, Intersect &ret)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSG::lock()
|
||||||
|
{
|
||||||
|
Shape::lock();
|
||||||
|
if(this->left)
|
||||||
|
{
|
||||||
|
this->left->lock();
|
||||||
|
}
|
||||||
|
if(this->right)
|
||||||
|
{
|
||||||
|
this->right->lock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CSG::dumpMe(FILE *fp)
|
void CSG::dumpMe(FILE *fp)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -90,7 +90,6 @@ bool Group::includes(Shape *b)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We are force to do them all the time */
|
|
||||||
if (this->unboxableObjectCount > 0)
|
if (this->unboxableObjectCount > 0)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -126,7 +125,7 @@ void Group::addObject(Shape *s)
|
|||||||
this->objectList = (Shape **)realloc(this->objectList, sizeof(Shape **) * this->allocatedObjectCount);
|
this->objectList = (Shape **)realloc(this->objectList, sizeof(Shape **) * this->allocatedObjectCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
s->parent = this;
|
s->setParent(this);
|
||||||
s->updateTransform();
|
s->updateTransform();
|
||||||
|
|
||||||
this->objectList[this->objectCount++] = s;
|
this->objectList[this->objectCount++] = s;
|
||||||
@@ -142,7 +141,7 @@ void Group::addObject(Shape *s)
|
|||||||
this->unboxableObjectList = (Shape **)realloc(this->unboxableObjectList, sizeof(Shape **) * this->allocatedUnboxableObjectCount);
|
this->unboxableObjectList = (Shape **)realloc(this->unboxableObjectList, sizeof(Shape **) * this->allocatedUnboxableObjectCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
s->parent = this;
|
s->setParent(this);
|
||||||
s->updateTransform();
|
s->updateTransform();
|
||||||
|
|
||||||
this->unboxableObjectList[this->unboxableObjectCount++] = s;
|
this->unboxableObjectList[this->unboxableObjectCount++] = s;
|
||||||
@@ -270,3 +269,27 @@ void Group::dumpMe(FILE *fp)
|
|||||||
}
|
}
|
||||||
Shape::dumpMe(fp);
|
Shape::dumpMe(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Group::lock()
|
||||||
|
{
|
||||||
|
Shape::lock();
|
||||||
|
|
||||||
|
/* Now notify included object they have to lock */
|
||||||
|
int i;
|
||||||
|
if (this->objectCount > 0)
|
||||||
|
{
|
||||||
|
for (i = 0 ; i < this->objectCount ; i++)
|
||||||
|
{
|
||||||
|
this->objectList[i]->lock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->unboxableObjectCount > 0)
|
||||||
|
{
|
||||||
|
for(i = 0; i < this->unboxableObjectCount; i++)
|
||||||
|
{
|
||||||
|
this->unboxableObjectList[i]->lock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -99,7 +99,7 @@ void OBJFile::addGroup(Group *group)
|
|||||||
{
|
{
|
||||||
this->baseGroup->addObject(group);
|
this->baseGroup->addObject(group);
|
||||||
|
|
||||||
group->parent = this;
|
group->setParent(this);
|
||||||
group->updateTransform();
|
group->updateTransform();
|
||||||
this->bounds | group->getBounds();
|
this->bounds | group->getBounds();
|
||||||
|
|
||||||
@@ -461,3 +461,10 @@ int OBJFile::execLine(int argc, char *argv[], uint32_t currentLine)
|
|||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OBJFile::lock()
|
||||||
|
{
|
||||||
|
Shape::lock();
|
||||||
|
|
||||||
|
this->baseGroup->lock();
|
||||||
|
}
|
||||||
@@ -15,12 +15,14 @@
|
|||||||
|
|
||||||
Shape::Shape(ShapeType type)
|
Shape::Shape(ShapeType type)
|
||||||
{
|
{
|
||||||
|
this->locked = false;
|
||||||
this->parent = nullptr;
|
this->parent = nullptr;
|
||||||
this->dropShadow = true;
|
this->dropShadow = true;
|
||||||
this->type = type;
|
this->type = type;
|
||||||
this->localTransformMatrix = Matrix4().identity();
|
this->localTransformMatrix = Matrix4().identity();
|
||||||
this->updateTransform();
|
|
||||||
this->materialSet = false;
|
this->materialSet = false;
|
||||||
|
|
||||||
|
this->updateTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
Intersect Shape::intersect(Ray r)
|
Intersect Shape::intersect(Ray r)
|
||||||
@@ -51,6 +53,8 @@ Tuple Shape::normalAt(Tuple point, Intersection *hit)
|
|||||||
|
|
||||||
void Shape::updateTransform()
|
void Shape::updateTransform()
|
||||||
{
|
{
|
||||||
|
if (this->locked) return;
|
||||||
|
|
||||||
this->transformMatrix = this->localTransformMatrix;
|
this->transformMatrix = this->localTransformMatrix;
|
||||||
if (this->parent != nullptr)
|
if (this->parent != nullptr)
|
||||||
{
|
{
|
||||||
@@ -63,6 +67,8 @@ void Shape::updateTransform()
|
|||||||
|
|
||||||
void Shape::setTransform(Matrix transform)
|
void Shape::setTransform(Matrix transform)
|
||||||
{
|
{
|
||||||
|
if (this->locked) return;
|
||||||
|
|
||||||
this->localTransformMatrix = transform;
|
this->localTransformMatrix = transform;
|
||||||
this->updateTransform();
|
this->updateTransform();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -201,3 +201,25 @@ TEST(ShapeTest, Test_the_bouding_box_of_the_translated_shape)
|
|||||||
ASSERT_EQ(res.min, b.min);
|
ASSERT_EQ(res.min, b.min);
|
||||||
ASSERT_EQ(res.max, b.max);
|
ASSERT_EQ(res.max, b.max);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(ShapeTest, A_lock_shape_can_t_have_transformation_changed)
|
||||||
|
{
|
||||||
|
TestShape t = TestShape();
|
||||||
|
t.setTransform(translation(10, 0, 0));
|
||||||
|
|
||||||
|
BoundingBox b = BoundingBox(Point(9, -1, -1), Point(11, 1, 1));
|
||||||
|
|
||||||
|
BoundingBox res = t.getBounds();
|
||||||
|
|
||||||
|
ASSERT_EQ(res.min, b.min);
|
||||||
|
ASSERT_EQ(res.max, b.max);
|
||||||
|
|
||||||
|
t.lock();
|
||||||
|
|
||||||
|
t.setTransform(translation(-10, -10,-10));
|
||||||
|
|
||||||
|
res = t.getBounds();
|
||||||
|
|
||||||
|
ASSERT_EQ(res.min, b.min);
|
||||||
|
ASSERT_EQ(res.max, b.max);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user