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; }
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())); }
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(); }
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); }
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(); }