bool AttributeAttractRepelParticleAffector::affect(ParticleSystemRefPtr System, Int32 ParticleIndex, const Time& elps) { if(System != NULL) { Vec3f Displacement(System->getSecPosition(ParticleIndex) - System->getPosition(ParticleIndex) ); Real32 Distance(Displacement.squareLength()); if((Distance > getMinDistance()*getMinDistance()) && (Distance < getMaxDistance()*getMaxDistance())) { Distance = osgSqrt(Distance); Displacement.normalize(); Real32 t((getQuadratic() * (Distance*Distance) + getLinear() * Distance + getConstant())*elps); if(t > Distance) { t=Distance; } System->setPosition(System->getPosition(ParticleIndex) + (Displacement * t),ParticleIndex) ; } } return false; }
bool ofxArtool5::setupCamera(string pthCamParam, ofVec2f _camSize, ofVec2f _viewportSize, ofPixelFormat pf){ ARParam cParam; AR_PIXEL_FORMAT pixFormat = toAR(pf); const char * cPathCamParam = ofToDataPath(pthCamParam).c_str(); camSize=_camSize; viewportSize=_viewportSize; if(arParamLoad(cPathCamParam, 1, &cParam)){ ofLogError("ofxArtool5::setupCamera()", "error loading param file"); return false; } if(cParam.xsize!=camSize.x||cParam.ysize!=camSize.y){ ofLogWarning("ofxArtool5::setupCamera()","camera param needs resizing"); arParamChangeSize(&cParam, camSize.x, camSize.y, &cParam); } if((gCparamLT = arParamLTCreate(&cParam, AR_PARAM_LT_DEFAULT_OFFSET))==NULL){ ofLogError("ofxArtool5::setupCamera()","Error: arParamLTCreate"); return false; } if(artMode==ART_PATTERN){ if((gARHandle = arCreateHandle(gCparamLT))==NULL){ ofLogError("ofxArtool5::setupCamera()","Error: arCreateHandle"); return false; } if(arSetPixelFormat(gARHandle, pixFormat)<0){ ofLogError("ofxArtool5::setupCamera()","Error arSetPixelFormat"); return false; } if(arSetDebugMode(gARHandle, AR_DEBUG_DISABLE)<0){ ofLogError("ofxArtool5::setupCamera()","Error arSetDebugMode"); return false; } if((gAR3DHandle = ar3DCreateHandle(&cParam))==NULL){ ofLogError("ofxArtool5::setupCamera()","Error ar3DCreateHandle"); return false; } }else if(artMode==ART_NFT){ arglCameraFrustumRH(&(gCparamLT->param), getMinDistance(), getMaxDistance(), cameraLens); } cvColorFrame.allocate(camSize.x, camSize.y); cvGrayFrame.allocate(camSize.x, camSize.y); return true; }
// Dijkstra 알고리즘 int *shortestPathDijkstra(LinkedGraph* pGraph, int startVertexID) { int *pReturn = NULL; int *pSelected = NULL; int nodeCount = 0, maxNodeCount = 0; int i = 0, j = 0, weight = 0; int vertexID = 0, y_w = 0, y_v = 0; ListNode *pListNode = NULL; LinkedList *pEdgeList = NULL; if (pGraph == NULL) { printf("Graph is NULL\n"); return pReturn; } maxNodeCount = getMaxVertexCountLG(pGraph); nodeCount = getVertexCountLG(pGraph); pReturn = (int *)malloc(sizeof(int) * maxNodeCount); pSelected = (int *)malloc(sizeof(int) * maxNodeCount); if (pReturn == NULL || pSelected == NULL) { if (pReturn != NULL) free(pReturn); printf("오류, 메모리 할당 in shortestPathDijkstra()\n"); return NULL; } // Step 0. 초기화 for(i = 0; i < maxNodeCount; i++) { if (i == startVertexID) { pReturn[i] = 0; } else { if (pGraph->pVertex[i] == USED) { pSelected[i] = TRUE; pReturn[i] = getEdgeWeight(pGraph, startVertexID, i); } else { pSelected[i] = FALSE; pReturn[i] = MAX_INT; } } } for(i = 0; i < maxNodeCount; i++) { printf("(%d,%d)->%d\n", startVertexID, i, pReturn[i]); } for(i = 0; i < nodeCount - 1; i++) { printf("[%d]-Iteration\n", i+1); // Step-1. // 집합 S중 최단 거리를 가지는 정점(vertexID)을 선택 vertexID = getMinDistance(pReturn, pSelected, maxNodeCount); pSelected[vertexID] = FALSE; // 선택된 정점(vertexID)에 인접한 정점들에 대해 거리 변경 조건 점검. pEdgeList = pGraph->ppAdjEdge[vertexID]; pListNode = pEdgeList->headerNode.pLink; while(pListNode != NULL) { int toVertexID = pListNode->data.vertexID; int weight = pListNode->data.weight; // y_v + c_v,w 와 y_w 비교 y_v = pReturn[vertexID]; y_w = pReturn[toVertexID]; if (y_v + weight < y_w) { pReturn[toVertexID] = y_v + weight; } pListNode = pListNode->pLink; } for(j = 0; j < maxNodeCount; j++) { printf("\t(%d,%d)->%d\n", startVertexID, j, pReturn[j]); } } free(pSelected); return pReturn; }
void simpleFluidEmitter::omniFluidEmitter( MFnFluid& fluid, const MMatrix& fluidWorldMatrix, int plugIndex, MDataBlock& block, double dt, double conversion, double dropoff ) //============================================================================== // // Method: // // simpleFluidEmitter::omniFluidEmitter // // Description: // // Emits fluid from a point, or from a set of object control points. // // Parameters: // // fluid: fluid into which we are emitting // fluidWorldMatrix: object->world matrix for the fluid // plugIndex: identifies which fluid connected to the emitter // we are emitting into // block: datablock for the emitter, to retrieve attribute // values // dt: time delta for this frame // conversion: mapping from UI emission rates to internal units // dropoff: specifies how much emission rate drops off as // we move away from each emission point. // // Notes: // // If no owner object is present for the emitter, we simply emit from // the emitter position. If an owner object is present, then we emit // from each control point of that object in an identical fashion. // // To associate an owner object with an emitter, use the // addDynamic MEL command, e.g. "addDynamic simpleFluidEmitter1 pPlane1". // //============================================================================== { // find the positions that we need to emit from // MVectorArray emitterPositions; // first, try to get them from an owner object, which will have its // "ownerPositionData" attribute feeding into the emitter. These // values are in worldspace // bool gotOwnerPositions = false; MObject ownerShape = getOwnerShape(); if( ownerShape != MObject::kNullObj ) { MStatus status; MDataHandle hOwnerPos = block.inputValue( mOwnerPosData, &status ); if( status == MS::kSuccess ) { MObject dOwnerPos = hOwnerPos.data(); MFnVectorArrayData fnOwnerPos( dOwnerPos ); MVectorArray posArray = fnOwnerPos.array( &status ); if( status == MS::kSuccess ) { // assign vectors from block to ownerPosArray. // for( unsigned int i = 0; i < posArray.length(); i ++ ) { emitterPositions.append( posArray[i] ); } gotOwnerPositions = true; } } } // there was no owner object, so we just use the emitter position for // emission. // if( !gotOwnerPositions ) { MPoint emitterPos = getWorldPosition(); emitterPositions.append( emitterPos ); } // get emission rates for density, fuel, heat, and emission color // double densityEmit = fluidDensityEmission( block ); double fuelEmit = fluidFuelEmission( block ); double heatEmit = fluidHeatEmission( block ); bool doEmitColor = fluidEmitColor( block ); MColor emitColor = fluidColor( block ); // rate modulation based on frame time, user value conversion factor, and // standard emitter "rate" value (not actually exposed in most fluid // emitters, but there anyway). // double theRate = getRate(block) * dt * conversion; // get voxel dimensions and sizes (object space) // double size[3]; unsigned int res[3]; fluid.getDimensions( size[0], size[1], size[2] ); fluid.getResolution( res[0], res[1], res[2] ); // voxel sizes double dx = size[0] / res[0]; double dy = size[1] / res[1]; double dz = size[2] / res[2]; // voxel centers double Ox = -size[0]/2; double Oy = -size[1]/2; double Oz = -size[2]/2; // emission will only happen for voxels whose centers lie within // "minDist" and "maxDist" of an emitter position // double minDist = getMinDistance( block ); double maxDist = getMaxDistance( block ); // bump up the min/max distance values so that they // are both > 0, and there is at least about a half // voxel between the min and max values, to prevent aliasing // artifacts caused by emitters missing most voxel centers // MTransformationMatrix fluidXform( fluidWorldMatrix ); double fluidScale[3]; fluidXform.getScale( fluidScale, MSpace::kWorld ); // compute smallest voxel diagonal length double wsX = fabs(fluidScale[0]*dx); double wsY = fabs(fluidScale[1]*dy); double wsZ = fabs(fluidScale[2]*dz); double wsMin = MIN( MIN( wsX, wsY), wsZ ); double wsMax = MAX( MAX( wsX, wsY), wsZ ); double wsDiag = wsMin * sqrt(3.0); // make sure emission range is bigger than 0.5 voxels if ( maxDist <= minDist || maxDist <= (wsDiag/2.0) ) { if ( minDist < 0 ) minDist = 0; maxDist = minDist + wsDiag/2.0; dropoff = 0; } // Now, it's time to actually emit into the fluid: // // foreach emitter point // foreach voxel // - select some points in the voxel // - compute a dropoff function from the emitter point // - emit an appropriate amount of fluid into the voxel // // Since we've already expanded the min/max distances to cover // the smallest voxel dimension, we should only need 1 sample per // voxel, unless the voxels are highly non-square. We increase the // number of samples in these cases. // // If the "jitter" flag is enabled, we jitter each sample position, // using the rangen() function, which keeps track of independent // random states for each fluid, to make sure that results are // repeatable for multiple simulation runs. // // basic sample count int numSamples = 1; // increase samples if necessary for non-square voxels if(wsMin >.00001) { numSamples = (int)(wsMax/wsMin + .5); if(numSamples > 8) numSamples = 8; if(numSamples < 1) numSamples = 1; } bool jitter = fluidJitter(block); if( !jitter ) { // I don't have a good uniform sample generator for an // arbitrary number of samples. It would be a good idea to use // one here. For now, just use 1 sample for the non-jittered case. // numSamples = 1; } for( unsigned int p = 0; p < emitterPositions.length(); p++ ) { MPoint emitterWorldPos = emitterPositions[p]; // loop through all voxels, looking for ones that lie at least // partially within the dropoff field around this emitter point // for( unsigned int i = 0; i < res[0]; i++ ) { double x = Ox + i*dx; for( unsigned int j = 0; j < res[1]; j++ ) { double y = Oy + j*dy; for( unsigned int k = 0; k < res[2]; k++ ) { double z = Oz + k*dz; int si; for( si = 0; si < numSamples; si++ ) { // compute sample point (fluid object space) // double rx, ry, rz; if( jitter ) { rx = x + randgen()*dx; ry = y + randgen()*dy; rz = z + randgen()*dz; } else { rx = x + 0.5*dx; ry = y + 0.5*dy; rz = z + 0.5*dz; } // compute distance from sample to emitter point // MPoint point( rx, ry, rz ); point *= fluidWorldMatrix; MVector diff = point - emitterWorldPos; double distSquared = diff * diff; double dist = diff.length(); // discard if outside min/max range // if( (dist < minDist) || (dist > maxDist) ) { continue; } // drop off the emission rate according to the falloff // parameter, and divide to accound for multiple samples // in the voxel // double distDrop = dropoff * distSquared; double newVal = theRate * exp( -distDrop ) / (double)numSamples; // emit density/heat/fuel/color into the current voxel // if( newVal != 0 ) { fluid.emitIntoArrays( (float) newVal, i, j, k, (float)densityEmit, (float)heatEmit, (float)fuelEmit, doEmitColor, emitColor ); } float *fArray = fluid.falloff(); if( fArray != NULL ) { MPoint midPoint( x+0.5*dx, y+0.5*dy, z+0.5*dz ); midPoint.x *= 0.2; midPoint.y *= 0.2; midPoint.z *= 0.2; float fdist = (float) sqrt( midPoint.x*midPoint.x + midPoint.y*midPoint.y + midPoint.z*midPoint.z ); fdist /= sqrtf(3.0f); fArray[fluid.index(i,j,k)] = 1.0f-fdist; } } } } } } }
float sfSoundStream_getMinDistance(const sfSoundStream* soundStream) { CSFML_CALL_RETURN(soundStream, getMinDistance(), 0.f); }
float sfSound_getMinDistance(const sfSound* sound) { CSFML_CALL_RETURN(sound, getMinDistance(), 0.f); }