inline
int
SliceExtractor<DataSetParam,ScalarExtractorParam,SliceParam>::extractSliceFragment(
	const typename SliceExtractor<DataSetParam,ScalarExtractorParam,SliceParam>::Cell& cell)
	{
	/* Determine cell vertex offsets and case index: */
	Scalar cvos[CellTopology::numVertices];
	int caseIndex=0x0;
	for(int i=0;i<CellTopology::numVertices;++i)
		{
		cvos[i]=slicePlane.calcDistance(cell.getVertexPosition(i));
		if(cvos[i]>=Scalar(0))
			caseIndex|=1<<i;
		}
	
	/* Calculate the intersection points: */
	int numPoints;
	typename Vertex::Position edgeVertices[CellTopology::numEdges];
	VScalar edgeValues[CellTopology::numEdges];
	int edge;
	for(numPoints=0;(edge=CaseTable::edgeIndices[caseIndex][numPoints])>=0;++numPoints)
		{
		/* Calculate intersection point on the edge: */
		int vi0=CellTopology::edgeVertexIndices[edge][0];
		int vi1=CellTopology::edgeVertexIndices[edge][1];
		Scalar w1=(Scalar(0)-cvos[vi0])/(cvos[vi1]-cvos[vi0]);
		edgeVertices[numPoints]=cell.calcEdgePosition(edge,w1).getComponents();
		VScalar val0=cell.getVertexValue(vi0,scalarExtractor);
		VScalar val1=cell.getVertexValue(vi1,scalarExtractor);
		Scalar w0=Scalar(1)-w1;
		edgeValues[numPoints]=val0*VScalar(w0)+val1*VScalar(w1);
		}
	
	/* Store the resulting fragment in the slice: */
	for(int i=2;i<numPoints;++i)
		{
		Vertex* vPtr=slice->getNextTriangleVertices();
		vPtr[0].texCoord[0]=edgeValues[0];
		vPtr[0].position=edgeVertices[0];
		vPtr[1].texCoord[0]=edgeValues[i-1];
		vPtr[1].position=edgeVertices[i-1];
		vPtr[2].texCoord[0]=edgeValues[i];
		vPtr[2].position=edgeVertices[i];
		slice->addTriangle();
		}
	
	return caseIndex;
	}
Exemple #2
0
inline
typename DataSet<DSParam,VScalarParam,DataValueParam>::DestScalar
DataSet<DSParam,VScalarParam,DataValueParam>::Locator::calcScalar(
	const Visualization::Abstract::ScalarExtractor* scalarExtractor) const
	{
	/* Convert the extractor base class pointer to the proper type: */
	const ScalarExtractor* myScalarExtractor=dynamic_cast<const ScalarExtractor*>(scalarExtractor);
	if(myScalarExtractor==0)
		Misc::throwStdErr("DataSet::Locator::calcScalar: Mismatching scalar extractor type");
	
	/* Check if the locator is valid: */
	if(!valid)
		Misc::throwStdErr("DataSet::Locator::calcScalar: Attempt to evaluate invalid locator");
		
	/* Calculate and return the value: */
	return VScalar(dsl.calcValue(myScalarExtractor->getSe()));
	}
Exemple #3
0
void ArtDTrack::processAsciiData(void)
	{
	while(true)
		{
		/* Wait for the next data message from the DTrack daemon: */
		char messageBuffer[4096];
		size_t messageSize=dataSocket.receiveMessage(messageBuffer,sizeof(messageBuffer)-1);
		
		/* Newline-terminate the message: */
		messageBuffer[messageSize]='\n';
		
		/* Parse the received message: */
		char* mPtr=messageBuffer;
		char* mEnd=messageBuffer+messageSize;
		while(mPtr<mEnd)
			{
			/* Find the end of the current line: */
			char* lineEnd;
			for(lineEnd=mPtr;*lineEnd!='\n';++lineEnd)
				;
			
			/* Skip whitespace: */
			while(mPtr<lineEnd&&isspace(*mPtr))
				++mPtr;
			
			/* Get the line identifier: */
			char* idStart=mPtr;
			while(mPtr<lineEnd&&!isspace(*mPtr))
				++mPtr;
			
			/* Determine the type of the line: */
			int lineType=-1;
			if(mPtr-idStart==2&&strncasecmp(idStart,"6d",2)==0)
				lineType=0;
			else if(mPtr-idStart==3&&strncasecmp(idStart,"6df",3)==0)
				lineType=1;
			else if(mPtr-idStart==4&&strncasecmp(idStart,"6df2",4)==0)
				lineType=2;
			else if(mPtr-idStart==4&&strncasecmp(idStart,"6dmt",4)==0)
				lineType=3;
			else if(mPtr-idStart==2&&strncasecmp(idStart,"3d",2)==0)
				lineType=4;
			
			/* Process the line: */
			if(lineType>=0)
				{
				if(lineType==2)
					{
					/* Skip the number of defined flysticks: */
					readInt(mPtr);
					}
				
				/* Read the number of reported bodies: */
				int numBodies=readInt(mPtr);
				
				/* Parse each body: */
				for(int body=0;body<numBodies;++body)
					{
					/* Find the first opening bracket: */
					while(mPtr<lineEnd&&isspace(*mPtr))
						++mPtr;
					if(*mPtr!='[')
						break; // Ignore the rest of the line
					++mPtr;
					
					/* Read the body's ID: */
					int id=readInt(mPtr);
					Device* device=deviceIdToIndex[id]>=0?&devices[deviceIdToIndex[id]]:0;
					
					/* Skip the quality value: */
					float(readFloat(mPtr));
					
					if(lineType==1||lineType==3)
						{
						/* Read the button bit flag: */
						unsigned int bits=readUint(mPtr);
						
						if(device!=0)
							{
							/* Set the button states: */
							for(int i=0;i<32&&i<device->numButtons;++i)
								{
								setButtonState(device->firstButtonIndex+i,(bits&0x1)!=0x0);
								bits>>=1;
								}
							}
						}
					
					int numButtons=0;
					int numValuators=0;
					if(lineType==2)
						{
						/* Read the number of buttons and valuators: */
						numButtons=readInt(mPtr);
						numValuators=readInt(mPtr);
						}
					
					/* Find the first closing bracket: */
					while(mPtr<lineEnd&&isspace(*mPtr))
						++mPtr;
					if(*mPtr!=']')
						break; // Ignore the rest of the line
					++mPtr;
					
					/* Find the second opening bracket: */
					while(mPtr<lineEnd&&isspace(*mPtr))
						++mPtr;
					if(*mPtr!='[')
						break; // Ignore the rest of the line
					++mPtr;
					
					/* Read the body's position: */
					Vector pos;
					for(int i=0;i<3;++i)
						pos[i]=VScalar(readFloat(mPtr));
					
					Rotation orient=Rotation::identity;
					if(lineType==0||lineType==1)
						{
						/* Read the body's orientation angles: */
						VScalar angles[3];
						for(int i=0;i<3;++i)
							angles[i]=VScalar(readFloat(mPtr));
						
						/* Calculate the body's orientation quaternion: */
						orient*=Rotation::rotateX(Math::rad(angles[0]));
						orient*=Rotation::rotateY(Math::rad(angles[1]));
						orient*=Rotation::rotateZ(Math::rad(angles[2]));
						}
					
					/* Find the second closing bracket: */
					while(mPtr<lineEnd&&isspace(*mPtr))
						++mPtr;
					if(*mPtr!=']')
						break; // Ignore the rest of the line
					++mPtr;
					
					if(lineType!=4)
						{
						/* Find the third opening bracket: */
						while(mPtr<lineEnd&&isspace(*mPtr))
							++mPtr;
						if(*mPtr!='[')
							break; // Ignore the rest of the line
						++mPtr;
						}
					
					if(lineType==2||lineType==3)
						{
						/* Read the body's orientation matrix (yuck!): */
						Geometry::Matrix<VScalar,3,3> matrix;
						for(int j=0;j<3;++j)
							for(int i=0;i<3;++i)
								matrix(i,j)=VScalar(readFloat(mPtr));
						
						/* Calculate the body's orientation quaternion: */
						orient=Rotation::fromMatrix(matrix);
						
						/* Find the third closing bracket: */
						while(mPtr<lineEnd&&isspace(*mPtr))
							++mPtr;
						if(*mPtr!=']')
							break; // Ignore the rest of the line
						++mPtr;
						}
					else if(lineType!=4)
						{
						/* Ignore the body's orientation matrix: */
						while(mPtr<lineEnd&&*mPtr!=']')
							++mPtr;
						if(*mPtr!=']') // Ignore the rest of the line
							break;
						}
					
					if(lineType==2)
						{
						/* Find the fourth opening bracket: */
						while(mPtr<lineEnd&&isspace(*mPtr))
							++mPtr;
						if(*mPtr!='[')
							break; // Ignore the rest of the line
						++mPtr;
						
						/* Read the flystick's button bits: */
						for(int bitIndex=0;bitIndex<numButtons;bitIndex+=32)
							{
							/* Read the next button bit mask: */
							unsigned int bits=readUint(mPtr);
							
							if(device!=0)
								{
								/* Set the device's button values: */
								for(int i=0;i<32;++i)
									{
									/* Set the button state if the button is valid: */
									if(bitIndex+i<device->numButtons)
										setButtonState(device->firstButtonIndex+bitIndex+i,(bits&0x1)!=0x0);
									bits>>=1;
									}
								}
							}
						
						/* Read the flystick's valuator values: */
						for(int i=0;i<numValuators;++i)
							{
							/* Read the next valuator value: */
							float value=float(readFloat(mPtr));
							
							/* Set the valuator value if the valuator is valid: */
							if(device!=0&&i<device->numValuators)
								setValuatorState(device->firstValuatorIndex+i,value);
							}
						
						/* Find the fourth closing bracket: */
						while(mPtr<lineEnd&&isspace(*mPtr))
							++mPtr;
						if(*mPtr!=']')
							break; // Ignore the rest of the line
						++mPtr;
						}
					
					/* Check if this body has been configured as a device: */
					if(device!=0)
						{
						/* Set the device's tracker state: */
						trackerStates[deviceIdToIndex[id]].positionOrientation=PositionOrientation(pos,orient);
						}
					}
				}
			
			/* Go to the start of the next line: */
			mPtr=lineEnd+1;
			}
		
		/* Update all tracker states (including those that were not updated): */
		for(int i=0;i<getNumTrackers();++i)
			setTrackerState(i,trackerStates[i]);
		}
Visualization::Abstract::DataSet* CitcomSRegionalASCIIFile::load(const std::vector<std::string>& args,Cluster::MulticastPipe* pipe) const
	{
	bool master=pipe==0||pipe->isMaster();
	
	/* Create the result data set: */
	Misc::SelfDestructPointer<EarthDataSet<DataSet> > result(new EarthDataSet<DataSet>(args));
	result->setFlatteningFactor(0.0);
	result->getSphericalCoordinateTransformer()->setColatitude(true);
	
	/* Parse command line parameters related to the grid definition file: */
	std::vector<std::string>::const_iterator argIt=args.begin();
	bool storeSphericals=false;
	while((*argIt)[0]=='-')
		{
		/* Parse the command line parameter: */
		if(*argIt=="-storeCoords")
			storeSphericals=true;
		
		++argIt;
		}
	
	/* Parse the run's configuration file: */
	std::string fullCfgName=getFullPath(*argIt);
	IO::FilePtr cfgFile(openFile(fullCfgName,pipe));
	std::string dataDir;
	std::string dataFileName;
	int numSurfaces=0;
	DS::Index numCpus(0,0,0);
	DS::Index numVertices(0,0,0);
	parseCitcomSCfgFile(fullCfgName,cfgFile,dataDir,dataFileName,numSurfaces,numCpus,numVertices);
	if(numSurfaces==0||numCpus.calcIncrement(-1)==0||numVertices.calcIncrement(-1)==0)
		Misc::throwStdErr("CitcomSRegionalASCIIFile::load: %s is not a valid CitcomS configuration file",fullCfgName.c_str());
	
	/* Check if it's really a regional model: */
	if(numSurfaces!=1)
		Misc::throwStdErr("CitcomSRegionalASCIIFile::load: configuration file %s does not describe a regional model; use CitcomSGlobalASCIIFile instead",fullCfgName.c_str());
	
	/* Initialize the data set: */
	DS& dataSet=result->getDs();
	dataSet.setGrid(numVertices);
	
	/* Initialize the result data set's data value: */
	DataValue& dataValue=result->getDataValue();
	dataValue.initialize(&dataSet,0);
	
	if(storeSphericals)
		{
		/* Add three slices to the data set: */
		static const char* coordSliceNames[3]={"Colatitude","Longitude","Radius"};
		for(int i=0;i<3;++i)
			{
			dataSet.addSlice();
			dataValue.addScalarVariable(coordSliceNames[i]);
			}
		}
	
	/* Compute the number of nodes per CPU: */
	DS::Index cpuNumVertices;
	for(int i=0;i<3;++i)
		cpuNumVertices[i]=(numVertices[i]-1)/numCpus[i]+1;
	int totalCpuNumVertices=cpuNumVertices.calcIncrement(-1);
	
	/* Prepare the spherical-to-Cartesian formula: */
	const double a=6378.14e3; // Equatorial radius in m
	// const double f=1.0/298.247; // Geoid flattening factor (not used, since there could be vector values)
	const double scaleFactor=1.0e-3; // Scale factor for Cartesian coordinates
	
	/* Read the grid coordinate files for all CPUs: */
	if(master)
		std::cout<<"Reading grid vertex positions...   0%"<<std::flush;
	int cpuCounter=0;
	DS::GridArray& grid=dataSet.getGrid();
	for(DS::Index cpuIndex(0);cpuIndex[0]<numCpus[0];cpuIndex.preInc(numCpus),++cpuCounter)
		{
		/* Open the CPU's coordinate file: */
		int cpuLinearIndex=(cpuIndex[1]*numCpus[0]+cpuIndex[0])*numCpus[2]+cpuIndex[2];
		std::string coordFileName=dataDir;
		coordFileName.append(dataFileName);
		coordFileName.append(".coord.");
		coordFileName.append(Misc::ValueCoder<int>::encode(cpuLinearIndex));
		IO::ValueSource coordReader(openFile(coordFileName,pipe));
		coordReader.skipWs();
		
		/* Read and check the header line: */
		try
			{
			/* Skip the unknown value: */
			coordReader.readInteger();
			
			/* Read the number of vertices: */
			if(coordReader.readInteger()!=totalCpuNumVertices)
				Misc::throwStdErr("CitcomSRegionalASCIIFile::load: Mismatching grid size in coordinate file %s",coordFileName.c_str());
			}
		catch(IO::ValueSource::NumberError err)
			{
			Misc::throwStdErr("CitcomSRegionalASCIIFile::load: Invalid header line in coordinate file %s",coordFileName.c_str());
			}
		
		/* Compute the CPU's base index in the surface's grid: */
		DS::Index cpuBaseIndex;
		for(int i=0;i<3;++i)
			cpuBaseIndex[i]=(cpuNumVertices[i]-1)*cpuIndex[i];
		
		/* Read the grid vertices: */
		DS::Index gridIndex;
		for(gridIndex[1]=0;gridIndex[1]<cpuNumVertices[1];++gridIndex[1])
			for(gridIndex[0]=0;gridIndex[0]<cpuNumVertices[0];++gridIndex[0])
				for(gridIndex[2]=0;gridIndex[2]<cpuNumVertices[2];++gridIndex[2])
					{
					/* Read the next grid vertex: */
					try
						{
						double colatitude=coordReader.readNumber();
						double longitude=coordReader.readNumber();
						double radius=coordReader.readNumber();
						
						/* Convert the vertex to Cartesian coordinates: */
						double latitude=Math::rad(90.0)-colatitude;
						double s0=Math::sin(latitude);
						double c0=Math::cos(latitude);
						double s1=Math::sin(longitude);
						double c1=Math::cos(longitude);
						double r=radius*a*scaleFactor;
						double xy=r*c0;
						DS::Index gIndex=cpuBaseIndex+gridIndex;
						DS::Point& vertex=grid(gIndex);
						vertex[0]=Scalar(xy*c1);
						vertex[1]=Scalar(xy*s1);
						vertex[2]=Scalar(r*s0);
						
						if(storeSphericals)
							{
							/* Store the original spherical coordinates as a scalar field: */
							dataSet.getVertexValue(0,gIndex)=Scalar(Math::deg(colatitude));
							dataSet.getVertexValue(1,gIndex)=Scalar(Math::deg(longitude));
							dataSet.getVertexValue(2,gIndex)=Scalar(r);
							}
						}
					catch(IO::ValueSource::NumberError err)
						{
						Misc::throwStdErr("CitcomSRegionalASCIIFile::load: Invalid vertex definition in coordinate file %s",coordFileName.c_str());
						}
					}
		if(master)
			std::cout<<"\b\b\b\b"<<std::setw(3)<<((cpuCounter+1)*100)/numCpus.calcIncrement(-1)<<"%"<<std::flush;
		}
	if(master)
		std::cout<<"\b\b\b\bdone"<<std::endl;
	
	/* Finalize the grid structure: */
	if(master)
		std::cout<<"Finalizing grid structure..."<<std::flush;
	dataSet.finalizeGrid();
	if(master)
		std::cout<<" done"<<std::endl;
	
	/* Read the time step index given on the command line: */
	++argIt;
	bool isNumber=true;
	int timeStepIndex=0;
	for(std::string::const_iterator tiIt=argIt->begin();isNumber&&tiIt!=argIt->end();++tiIt)
		{
		if(*tiIt>='0'&&*tiIt<='9')
			timeStepIndex=timeStepIndex*10+int(*tiIt-'0');
		else
			isNumber=false;
		}
	if(!isNumber)
		Misc::throwStdErr("CitcomSRegionalASCIIFile::load: no time step index provided");
	
	/* Read all data components given on the command line: */
	bool logNextScalar=false;
	bool nextVector=false;
	for(++argIt;argIt!=args.end();++argIt)
		{
		if(*argIt=="-log")
			logNextScalar=true;
		else if(*argIt=="-vector")
			nextVector=true;
		else
			{
			/* Remember the (base) slice index for this variable: */
			int sliceIndex=dataSet.getNumSlices();
			
			/* Check if it's the special-case velo two-variable file (bleargh): */
			bool isVeloFile=*argIt=="velo";
			if(isVeloFile||nextVector)
				{
				/* Add another vector variable to the data value: */
				int vectorVariableIndex=dataValue.addVectorVariable(argIt->c_str());
				if(master)
					std::cout<<"Reading vector variable "<<*argIt<<"...   0%"<<std::flush;
				
				/* Add seven new slices to the data set (3 components spherical and Cartesian each plus Cartesian magnitude): */
				static const char* componentNames[7]={" Colatitude"," Longitude"," Radius"," X"," Y"," Z"," Magnitude"};
				for(int i=0;i<7;++i)
					{
					dataSet.addSlice();
					dataValue.addScalarVariable(((*argIt)+componentNames[i]).c_str());
					}
				
				/* Set the vector variables' component indices: */
				for(int i=0;i<3;++i)
					dataValue.setVectorVariableScalarIndex(vectorVariableIndex,i,sliceIndex+3+i);
				
				/* Test for the special case of the velo file: */
				if(isVeloFile)
					{
					/* Add another scalar variable to the data value: */
					dataSet.addSlice();
					if(logNextScalar)
						dataValue.addScalarVariable("log(temp)");
					else
						dataValue.addScalarVariable("temp");
					}
				}
			else
				{
				/* Add another scalar variable to the data value: */
				dataSet.addSlice();
				if(logNextScalar)
					{
					std::string scalarName="log(";
					scalarName.append(*argIt);
					scalarName.push_back(')');
					dataValue.addScalarVariable(scalarName.c_str());
					if(master)
						std::cout<<"Reading scalar variable "<<scalarName<<"...   0%"<<std::flush;
					}
				else
					{
					dataValue.addScalarVariable(argIt->c_str());
					if(master)
						std::cout<<"Reading scalar variable "<<*argIt<<"...   0%"<<std::flush;
					}
				}
			
			/* Read data files for all CPUs: */
			cpuCounter=0;
			DS::GridArray& grid=dataSet.getGrid();
			for(DS::Index cpuIndex(0);cpuIndex[0]<numCpus[0];cpuIndex.preInc(numCpus),++cpuCounter)
				{
				/* Open the CPU's data value file: */
				int cpuLinearIndex=(cpuIndex[1]*numCpus[0]+cpuIndex[0])*numCpus[2]+cpuIndex[2];
				std::string dataValueFileName=dataDir;
				dataValueFileName.append(dataFileName);
				dataValueFileName.push_back('.');
				dataValueFileName.append(*argIt);
				dataValueFileName.push_back('.');
				dataValueFileName.append(Misc::ValueCoder<int>::encode(cpuLinearIndex));
				dataValueFileName.push_back('.');
				dataValueFileName.append(Misc::ValueCoder<int>::encode(timeStepIndex));
				IO::ValueSource dataValueReader(openFile(dataValueFileName,pipe));
				dataValueReader.skipWs();
				
				/* Read and check the header line(s) in the data value file: */
				try
					{
					int dataValueFileNumVertices1=totalCpuNumVertices;
					if(isVeloFile)
						{
						/* Read the first header line only found in velo files: */
						dataValueReader.readInteger();
						dataValueFileNumVertices1=dataValueReader.readInteger();
						dataValueReader.readNumber();
						}
					
					/* Read the common header line: */
					dataValueReader.readInteger();
					int dataValueFileNumVertices2=dataValueReader.readInteger();
					
					/* Check for consistency: */
					if(dataValueFileNumVertices1!=totalCpuNumVertices||dataValueFileNumVertices2!=totalCpuNumVertices)
						Misc::throwStdErr("CitcomSRegionalASCIIFile::load: Mismatching grid size in data value file %s",dataValueFileName.c_str());
					}
				catch(IO::ValueSource::NumberError err)
					{
					Misc::throwStdErr("CitcomSRegionalASCIIFile::load: Invalid header line in data value file %s",dataValueFileName.c_str());
					}
				
				/* Compute the CPU's base index in the surface's grid: */
				DS::Index cpuBaseIndex;
				for(int i=0;i<3;++i)
					cpuBaseIndex[i]=(cpuNumVertices[i]-1)*cpuIndex[i];
				
				/* Read the grid vertices: */
				DS::Index gridIndex;
				for(gridIndex[1]=0;gridIndex[1]<cpuNumVertices[1];++gridIndex[1])
					for(gridIndex[0]=0;gridIndex[0]<cpuNumVertices[0];++gridIndex[0])
						for(gridIndex[2]=0;gridIndex[2]<cpuNumVertices[2];++gridIndex[2])
							{
							/* Read the next vertex' value: */
							DS::Index index=cpuBaseIndex+gridIndex;
							
							try
								{
								if(isVeloFile||nextVector)
									{
									/* Read the vector components: */
									double colatitude=dataValueReader.readNumber();
									double longitude=dataValueReader.readNumber();
									double radius=dataValueReader.readNumber();
									
									/* Convert the vector from spherical to Cartesian coordinates: */
									const DS::Point& p=grid(index);
									double xy=Math::sqr(double(p[0]))+Math::sqr(double(p[1]));
									double r=xy+Math::sqr(double(p[2]));
									xy=Math::sqrt(xy);
									r=Math::sqrt(r);
									double s0=double(p[2])/r;
									double c0=xy/r;
									double s1=double(p[1])/xy;
									double c1=double(p[0])/xy;
									DataValue::VVector vector;
									vector[0]=VScalar(c1*(c0*radius+s0*colatitude)-s1*longitude);
									vector[1]=VScalar(s1*(c0*radius+s0*colatitude)+c1*longitude);
									vector[2]=VScalar(s0*radius-c0*colatitude);
									dataSet.getVertexValue(sliceIndex+0,index)=VScalar(colatitude);
									dataSet.getVertexValue(sliceIndex+1,index)=VScalar(longitude);
									dataSet.getVertexValue(sliceIndex+2,index)=VScalar(radius);
									for(int i=0;i<3;++i)
										dataSet.getVertexValue(sliceIndex+3+i,index)=vector[i];
									dataSet.getVertexValue(sliceIndex+6,index)=VScalar(Geometry::mag(vector));
									
									if(isVeloFile)
										{
										/* Read the temperature value: */
										double temp=dataValueReader.readNumber();
										dataSet.getVertexValue(sliceIndex+7,index)=logNextScalar?VScalar(Math::log10(temp)):VScalar(temp);
										}
									}
								else
									{
									/* Read the scalar value: */
									double value=dataValueReader.readNumber();
									dataSet.getVertexValue(sliceIndex,index)=logNextScalar?VScalar(Math::log10(value)):VScalar(value);
									}
								}
							catch(IO::ValueSource::NumberError err)
								{
								Misc::throwStdErr("CitcomSRegionalASCIIFile::load: Invalid vertex value definition in data value file %s",dataValueFileName.c_str());
								}
							}
				if(master)
					std::cout<<"\b\b\b\b"<<std::setw(3)<<((cpuCounter+1)*100)/numCpus.calcIncrement(-1)<<"%"<<std::flush;
				}
			if(master)
				std::cout<<"\b\b\b\bdone"<<std::endl;
			
			if(nextVector)
				nextVector=false;
			else
				logNextScalar=false;
			}
		}
	
	/* Return the result data set: */
	return result.releaseTarget();
	}
Exemple #5
0
void ViconTarsus::deviceThreadMethod(void)
	{
	while(true)
		{
		/* Wait for the next packet from the server: */
		int packetKind=pipe.read<int>();
		if(pipe.read<int>()==1) // Ignore request packets
			{
			switch(packetKind)
				{
				case 0:
				case 4:
					/* Shut down the thread method: */
					return;
				
				case 2:
					{
					/* Read the data packet: */
					int numPacketChannels=pipe.read<int>();
					if(numPacketChannels>numChannels)
						{
						/* Read the relevant channels: */
						pipe.read<double>(channelPacketBuffer,numChannels);
						
						/* Ignore all spurious channels: */
						for(int i=numChannels;i<numPacketChannels;++i)
							pipe.read<double>();
						numPacketChannels=numChannels;
						}
					else
						{
						/* Read all channels: */
						pipe.read<double>(channelPacketBuffer,numPacketChannels);
						}
					
					/* Process the data packet: */
					for(int trackerIndex=0;trackerIndex<getNumTrackers();++trackerIndex)
						{
						/* Get the tracker's position: */
						Vector translation;
						bool valid=true;
						for(int i=0;i<3;++i)
							{
							if(trackerChannelIndices[trackerIndex*6+i]<numPacketChannels)
								translation[i]=VScalar(channelPacketBuffer[trackerChannelIndices[trackerIndex*6+i]]);
							else
								valid=false;
							}
						
						if(valid)
							{
							if(trackerSixDofs[trackerIndex])
								{
								/* Get the tracker's orientation: */
								PositionOrientation::Rotation::Vector rotation;
								bool sixDof=true;
								for(int i=0;i<3;++i)
									{
									if(trackerChannelIndices[trackerIndex*6+3+i]<numPacketChannels)
										rotation[i]=RScalar(channelPacketBuffer[trackerChannelIndices[trackerIndex*6+3+i]]);
									else
										sixDof=false;
									}
								
								if(sixDof)
									{
									/* Set the 6-DOF tracker state: */
									trackerStates[trackerIndex].positionOrientation=PositionOrientation(translation,Rotation::rotateScaledAxis(rotation));
									}
								else
									{
									/* Set the 6-DOF tracker state with the previous orientation: */
									trackerStates[trackerIndex].positionOrientation=PositionOrientation(translation,trackerStates[trackerIndex].positionOrientation.getRotation());
									}
								}
							else
								{
								/* Set the 3-DOF tracker state: */
								trackerStates[trackerIndex].positionOrientation=PositionOrientation(translation,Rotation::identity);
								}
							}
						}
					
					/* Update all tracker states (including those that were not updated): */
					for(int i=0;i<getNumTrackers();++i)
						setTrackerState(i,trackerStates[i]);
					break;
					}
				
				default:
					/* Ignore the packet: */
					;
				}
			}
		}
	}
inline
SliceVolumeRenderer<Cartesian<ScalarParam,3,ValueParam>,ScalarExtractorParam>::SliceVolumeRenderer(
	const typename SliceVolumeRenderer<Cartesian<ScalarParam,3,ValueParam>,ScalarExtractorParam>::DataSet* sDataSet,
	const typename SliceVolumeRenderer<Cartesian<ScalarParam,3,ValueParam>,ScalarExtractorParam>::ScalarExtractor& sScalarExtractor,
	const GLColorMap* sColorMap,
	Comm::MulticastPipe* sPipe)
	:dataSet(sDataSet),
	 scalarExtractor(sScalarExtractor),
	 colorMap(sColorMap),
	 renderer(0),
	 transparencyGamma(1.0f)
	{
	/* Determine the data set's value range: */
	VScalar minValue,maxValue;
	typename DataSet::VertexIterator vIt=dataSet->beginVertices();
	minValue=maxValue=vIt->getValue(scalarExtractor);
	for(++vIt;vIt!=dataSet->endVertices();++vIt)
		{
		VScalar value=vIt->getValue(scalarExtractor);
		if(minValue>value)
			minValue=value;
		else if(maxValue<value)
			maxValue=value;
		}
	
	/* Create a palette renderer: */
	renderer=new PaletteRenderer;
	
	/* Create a voxel block: */
	int size[3];
	for(int i=0;i<3;++i)
		size[i]=dataSet->getNumVertices()[i];
	PaletteRenderer::Voxel* voxels;
	int increments[3];
	voxels=renderer->createVoxelBlock(size,0,PaletteRenderer::VERTEX_CENTERED,increments);
	
	/* Upload the data set's scalar values into the voxel block: */
	for(typename DataSet::Index index(0);index[0]<dataSet->getNumVertices()[0];index.preInc(dataSet->getNumVertices()))
		{
		/* Get the vertex' scalar value: */
		VScalar value=scalarExtractor.getValue(dataSet->getVertexValue(index));
		
		/* Convert the value to unsigned char: */
		PaletteRenderer::Voxel& voxel=voxels[index[0]*increments[0]+index[1]*increments[1]+index[2]*increments[2]];
		voxel=PaletteRenderer::Voxel(Math::floor((value-minValue)*VScalar(255)/(maxValue-minValue)+VScalar(0.5)));
		}
	renderer->finishVoxelBlock();
	
	/* Set the renderer's model space position and size: */
	renderer->setPosition(dataSet->getDomainBox().getOrigin(),dataSet->getDomainBox().getSize());
	
	/* Initialize volume renderer settings: */
	// renderer->setUseNPOTDTextures(true);
	renderer->setRenderingMode(PaletteRenderer::VIEW_PERPENDICULAR);
	renderer->setInterpolationMode(PaletteRenderer::LINEAR);
	renderer->setTextureFunction(PaletteRenderer::REPLACE);
	renderer->setSliceFactor(Scalar(2.0));
	renderer->setAutosaveGLState(true);
	renderer->setTextureCaching(true);
	renderer->setSharePalette(false);
	}
Exemple #7
0
void ArtDTrack::processAsciiData(void)
	{
	Vrui::VRDeviceState::TrackerState ts;
	ts.linearVelocity=Vrui::VRDeviceState::TrackerState::LinearVelocity::zero;
	ts.angularVelocity=Vrui::VRDeviceState::TrackerState::AngularVelocity::zero;
	
	while(true)
		{
		/* Wait for the next data message from the DTrack daemon: */
		char messageBuffer[4096];
		size_t messageSize=dataSocket.receiveMessage(messageBuffer,sizeof(messageBuffer)-1);
		
		/* Newline-terminate the message as a sentinel: */
		messageBuffer[messageSize]='\n';
		
		/* Parse the received message: */
		const char* mPtr=messageBuffer;
		const char* mEnd=messageBuffer+(messageSize+1);
		while(mPtr!=mEnd)
			{
			/* Skip whitespace, but not the line terminator: */
			while(*mPtr!='\n'&&isspace(*mPtr))
				++mPtr;
			
			/* Get the line's device report format: */
			DeviceReportFormat drf=parseDeviceReportFormat(mPtr,0,&mPtr);
			
			/* Process the line: */
			if(drf!=DRF_NUMFORMATS)
				{
				if(drf==DRF_6DF2)
					{
					/* Skip the number of defined flysticks: */
					readInt(mPtr);
					}
				
				/* Read the number of bodies in this report: */
				int numBodies=readInt(mPtr);
				
				/* Parse all body reports: */
				for(int body=0;body<numBodies;++body)
					{
					/* Check for opening bracket: */
					if(!expectChar('[',mPtr))
						break;
					
					/* Read the body's ID and find the corresponding device structure: */
					int id=readInt(mPtr);
					int deviceIndex=deviceIdToIndex[drf][id];
					Device* device=deviceIndex>=0?&devices[deviceIndex]:0;
					
					/* Read the quality value: */
					float quality=float(readFloat(mPtr));
					
					/* Read button/valuator or finger data depending on report format: */
					int numButtons=0;
					int numValuators=0;
					int numFingers=0;
					
					if(drf==DRF_6DF)
						{
						/* Read the button bit mask: */
						unsigned int buttonBits=readUint(mPtr);
						
						if(device!=0)
							{
							/* Set the device's button states: */
							for(int i=0;i<32&&i<device->numButtons;++i,buttonBits>>=1)
								setButtonState(device->firstButtonIndex+i,(buttonBits&0x1)!=0x0);
							}
						}
					if(drf==DRF_6DF2||drf==DRF_6DMT)
						{
						/* Read the number of buttons: */
						numButtons=readInt(mPtr);
						if(drf==DRF_6DF2)
							{
							/* Read the number of valuators: */
							numValuators=readInt(mPtr);
							}
						}
					if(drf==DRF_GL)
						{
						/* Skip the glove's handedness: */
						readInt(mPtr);
						
						/* Read the number of fingers: */
						numFingers=readInt(mPtr);
						}
					
					/* Check for closing bracket followed by opening bracket: */
					if(!expectChar(']',mPtr)||!expectChar('[',mPtr))
						break;
					
					Vector pos;
					Rotation orient=Rotation::identity;
					
					/* Read the body's 3D position: */
					for(int i=0;i<3;++i)
						pos[i]=VScalar(readFloat(mPtr));
					
					if(drf!=DRF_3D)
						{
						/* Read the body's 3D orientation: */
						if(drf==DRF_6D||drf==DRF_6DF)
							{
							/* Read the body's orientation angles: */
							VScalar angles[3];
							for(int i=0;i<3;++i)
								angles[i]=VScalar(readFloat(mPtr));
							
							/* Convert the orientation angles to a 3D rotation: */
							orient*=Rotation::rotateX(Math::rad(angles[0]));
							orient*=Rotation::rotateY(Math::rad(angles[1]));
							orient*=Rotation::rotateZ(Math::rad(angles[2]));
							}
					
						/* Check for closing bracket followed by opening bracket: */
						if(!expectChar(']',mPtr)||!expectChar('[',mPtr))
							break;
						
						if(drf==DRF_6DF2||drf==DRF_6DMT||drf==DRF_GL)
							{
							/* Read the body's orientation matrix (yuck!): */
							Geometry::Matrix<VScalar,3,3> matrix;
							for(int j=0;j<3;++j)
								for(int i=0;i<3;++i)
									matrix(i,j)=VScalar(readFloat(mPtr));
							
							if(quality>0.0f)
								{
								/* Calculate the body's orientation quaternion (YUCK!): */
								orient=Rotation::fromMatrix(matrix);
								}
							}
						else
							{
							/* Skip the body's orientation matrix: */
							for(int i=0;i<9;++i)
								readFloat(mPtr);
							}
						}
					
					/* Check for closing bracket: */
					if(!expectChar(']',mPtr))
						break;
					
					if(drf==DRF_6DF2)
						{
						/* Check for opening bracket: */
						if(!expectChar('[',mPtr))
							break;
						
						/* Read button states: */
						for(int bitIndex=0;bitIndex<numButtons;bitIndex+=32)
							{
							/* Read the next button bit mask: */
							unsigned int buttonBits=readUint(mPtr);
							
							if(device!=0)
								{
								/* Set the device's button states: */
								for(int i=0;i<32&&bitIndex+i<device->numButtons;++i,buttonBits>>=1)
									setButtonState(device->firstButtonIndex+bitIndex+i,(buttonBits&0x1)!=0x0);
								}
							}
						
						/* Read valuator states: */
						for(int i=0;i<numValuators;++i)
							{
							/* Read the next valuator value: */
							float value=float(readFloat(mPtr));
							
							/* Set the valuator value if the valuator is valid: */
							if(device!=0&&i<device->numValuators)
								setValuatorState(device->firstValuatorIndex+i,value);
							}
						
						/* Check for closing bracket: */
						if(!expectChar(']',mPtr))
							break;
						}
					
					if(drf==DRF_GL)
						{
						/* Skip all finger data for now: */
						bool error=false;
						for(int finger=0;finger<numFingers;++finger)
							{
							/* Check for opening bracket: */
							if(!expectChar('[',mPtr))
								{
								error=true;
								break;
								}
							
							/* Skip finger position: */
							for(int i=0;i<3;++i)
								readFloat(mPtr);
							
							/* Check for closing followed by opening bracket: */
							if(!expectChar(']',mPtr)||!expectChar('[',mPtr))
								{
								error=true;
								break;
								}
							
							/* Skip finger orientation: */
							for(int i=0;i<9;++i)
								readFloat(mPtr);
							
							/* Check for closing followed by opening bracket: */
							if(!expectChar(']',mPtr)||!expectChar('[',mPtr))
								{
								error=true;
								break;
								}
							
							/* Skip finger bending parameters: */
							for(int i=0;i<6;++i)
								readFloat(mPtr);
							
							/* Check for closing bracket: */
							if(!expectChar(']',mPtr))
								{
								error=true;
								break;
								}
							}
						
						/* Stop parsing the packet on syntax error: */
						if(error)
							break;
						}
					
					/* Check if this body has a valid position/orientation and has been configured as a device: */
					if(quality>0.0f&&device!=0)
						{
						/* Set the device's tracker state: */
						ts.positionOrientation=PositionOrientation(pos,orient);
						setTrackerState(deviceIndex,ts);
						}
					}
				}
			
			/* Skip the rest of the line: */
			while(*mPtr!='\n')
				++mPtr;
			
			/* Go to the next line: */
			++mPtr;
			}
		
		/* Tell the VR device manager that the current state has updated completely: */
		updateState();
		}