Dynamic scaling of the size of an object

Hi, everybody.

I work with Open Inventor and am trying to make an object rescale as the camera moves, so that it appears the same size, no matter how far away is it from the camera.

The camera moves when I press a key and I set the object to redraw its scenegraph for the new camera position. I load the geometry of the object from a file every time it is rerendered.

This works file when the camera moves away and I need to make the object bigger. But when the camera moves closer, the object does not get smaller! It stays the same size as it got when the camera was furhtest away.

Any ideas?

Here is some code:


//Main
int main(int argc, char *argv[])
{
SoOneShotSensor	*sensor = new SoOneShotSensor (simulationStep, NULL);
root->ref();

myObject = new genObject();
myObject->buildtree(root);
//Update Scene
sensor->schedule();
...
}

//simulationStep
void simulationStep(void *data, SoSensor *sensor)
{
	...
	SbVec3f *cameraPosition = new SbVec3f
				(myPerspectiveCamera->position.getValue()[0], 
				 myPerspectiveCamera->position.getValue()[1], myPerspectiveCamera->position.getValue()[2]);
	myObject->setScale(cameraPosition);
	myObject->buildtree(root);
	sensor->schedule();
}

//myObject->setScale(cameraPosition)
void genObject::setScale(SbVec3f *cameraPosition)
{
	this->cameraPosition = cameraPosition;
	SbVec3f tempPos = SbVec3f(this->getLatitude(), 
					  this->getAltitude(), 
					  this->getLongitude());
	
	
	if (tempPos.length() == 0)
	{
		this->scaleFactor = 1;
	} else 
	{
		this->newScaleFactor = cameraPosition->length() / tempPos.length();
		this->scaleFactor = this->newScaleFactor;
	}
}
//myObject->buildtree(root)
void genObject:: buildtree(SoSeparator *root)
{
	this->group = new SoSeparator();
	root->addChild(this->group);

	this->model = new SoFile;
	model->name.setValue("OwnObject.iv");

	...

	this->size = new SoScale();
	this->size->scaleFactor.setValue(this->getScale(), this->getScale(), this->getScale());
	
	this->group->addChild(this->size);
	this->group->addChild(model);

	
};

//genObject
#pragma once

class genObject
{
private:
	float altitude;
	float latitude;
	float longitude;
	float scaleFactor;
	float newScaleFactor;
	SbVec3f *cameraPosition;
	SoSeparator *group;
	SoScale *size;
	SoFile *model;


public:
	genObject();
	void setAltitude(float alt);
	void setLongitude(float lon);
	void setLatitude(float lat);
	void setScale(SbVec3f *cameraPosition);
	void buildtree(SoSeparator *root);

	float getAltitude() {return this->altitude;}
	float getLongitude(){return this->longitude;}
	float getLatitude() {return this->latitude;}
	float getScale() {return this->scaleFactor;}
	
public:
	~genObject(void);
};

If I remember correctly, it is as simple as computing the distance between the object and camera position, and scaling the object by that. You may need to tweak the default scale, and if the field of view can change, you may want to take that in account as well.

Alternatively, if the element is always on top of everything else (e.g. a pivot, manipulator etc), you can set up a new projection (and clear z-buffer if needed) and render your gizmos on top, with a fixed field of view, independently from the viewport contents.

I tried scale by the distance between the object and the camera. The scale factor changes accordingly, but the objects size does not (even when the scale factor decreases the object size remains as big as it was when the camera was furhtest away).

Another camera might be a good plan. I will trq it. In the meantime if anybody has encountered such problems with SoScale, let me know.

Mystery solved. In the actual code I have written SbVec3f *temp instead of SbVec3f temp. Wonder how it ever worked…

@remdul - a second camera works flawlessly. Thanks for the idea.