double Table3D::Interpolate(double coor1, double coor2, double coor3, int ivar) { InterpolatePoint(coor1, coor2, coor3); if ((ivar<0)||(ivar>=nvar)){ cerr << "Failed to access variable number " << ivar<< " , nvar= "<<nvar<<endl; throw(-1); } return Interpolate(ivar); }
void PressureTable::LookupSelectedCoeff(double &RoM, double &T0, double &E0, double &Gam0, double &a_Gam, double P, double Zm, double Zvar, double C) { InterpolatePoint(P, Zm, Zvar, C); RoM = Interpolate(0); T0 = Interpolate(1); E0 = Interpolate(2); Gam0 = Interpolate(3); a_Gam = Interpolate(4); }
void Table3D::InterpolatePoint(double coor1, double coor2, double coor3) { if ((coor1 != point[0])|| (coor2 != point[1])|| (coor3 != point[2])) { SetInterpPoint(coor1, coor2, coor3); InterpolatePoint(); } }
double Interpolation::getInterpolatedValue(Segment *segment, double time) { double START_TIME = segment->measuredValues.front()->measuredate; double END_TIME = segment->measuredValues.back()->measuredate; MeasuredValue *previous = NULL; MeasuredValue *actual = NULL; double result_ist; if (time < START_TIME) { return DBL_MAX; } else if (time > END_TIME) { return DBL_MAX; } else { for (size_t i = 0; i < segment->measuredValues.size(); i++) { actual = segment->measuredValues[i]; // if the actual time is bigger than the output time if (actual->measuredate == time && actual->ist != 0) { result_ist = segment->measuredValues[i]->ist; return result_ist; } if (time > actual->measuredate) { if (actual->ist != 0) { previous = actual; } } else { if (actual->ist != 0) { if (previous == NULL) { return DBL_MAX; } else { return InterpolatePoint(previous->ist, actual->ist, previous->measuredate, actual->measuredate, time); } } } } } return DBL_MAX; }
void PressureTable::LookupCoeff(double &RoM, double &T0, double &E0, double &Gam0, double &a_Gam, double &mu0, double &a_mu, double &lamOcp0, double &a_lamOcp, double &src_prog, double P, double Zm, double Zvar, double C) { InterpolatePoint(P, Zm, Zvar, C); RoM = Interpolate(0); T0 = Interpolate(1); E0 = Interpolate(2); Gam0 = Interpolate(3); a_Gam = Interpolate(4); mu0 = Interpolate(5); a_mu = Interpolate(6); lamOcp0 = Interpolate(7); a_lamOcp = Interpolate(8); src_prog = Interpolate(9); }
void IOHIDTableAcceleration::InterpolateFunction (const ACCEL_TABLE_ENTRY *lo, const ACCEL_TABLE_ENTRY *hi, double ratio, std::set<ACCEL_POINT> &result) { uint32_t hindex = 0; ACCEL_POINT ph0 = {0,0}; ACCEL_POINT ph1 = hi->point(hindex); for (uint32_t index = 0; index < lo->count(); index++) { ACCEL_POINT p = lo->point(index); while (p.x > ph1.x) { if (hindex < (hi->count() - 1)) { ph0 = ph1; ph1 = hi->point(++hindex); } else { break; } } result.insert(InterpolatePoint (p, ph0, ph1, ratio)); } }
void FIndirectLightingCache::UpdateBlock(FScene* Scene, FViewInfo* DebugDrawingView, FBlockUpdateInfo& BlockInfo) { const int32 NumSamplesPerBlock = BlockInfo.Block.TexelSize * BlockInfo.Block.TexelSize * BlockInfo.Block.TexelSize; FSHVectorRGB3 SingleSample; float DirectionalShadowing = 1; FVector SkyBentNormal(0, 0, 1); //always do point interpolation to get valid 3band single sample and directional data. InterpolatePoint(Scene, BlockInfo.Block, DirectionalShadowing, SingleSample, SkyBentNormal); if (CanIndirectLightingCacheUseVolumeTexture(GetFeatureLevel()) && !BlockInfo.Allocation->bPointSample) { static TArray<float> AccumulatedWeight; AccumulatedWeight.Reset(NumSamplesPerBlock); AccumulatedWeight.AddZeroed(NumSamplesPerBlock); //volume textures are encoded as two band, so no reason to waste perf interpolating 3 bands. static TArray<FSHVectorRGB2> AccumulatedIncidentRadiance; AccumulatedIncidentRadiance.Reset(NumSamplesPerBlock); AccumulatedIncidentRadiance.AddZeroed(NumSamplesPerBlock); // Interpolate SH samples from precomputed lighting samples and accumulate lighting data for an entire block InterpolateBlock(Scene, BlockInfo.Block, AccumulatedWeight, AccumulatedIncidentRadiance); static TArray<FFloat16Color> Texture0Data; static TArray<FFloat16Color> Texture1Data; static TArray<FFloat16Color> Texture2Data; Texture0Data.Reset(NumSamplesPerBlock); Texture1Data.Reset(NumSamplesPerBlock); Texture2Data.Reset(NumSamplesPerBlock); Texture0Data.AddUninitialized(NumSamplesPerBlock); Texture1Data.AddUninitialized(NumSamplesPerBlock); Texture2Data.AddUninitialized(NumSamplesPerBlock); const int32 FormatSize = GPixelFormats[PF_FloatRGBA].BlockBytes; check(FormatSize == sizeof(FFloat16Color)); // Encode the SH samples into a texture format // Note the single sample is updated even if this is a volume allocation, because translucent materials only use the single sample EncodeBlock(DebugDrawingView, BlockInfo.Block, AccumulatedWeight, AccumulatedIncidentRadiance, Texture0Data, Texture1Data, Texture2Data); // Setup an update region const FUpdateTextureRegion3D UpdateRegion( BlockInfo.Block.MinTexel.X, BlockInfo.Block.MinTexel.Y, BlockInfo.Block.MinTexel.Z, 0, 0, 0, BlockInfo.Block.TexelSize, BlockInfo.Block.TexelSize, BlockInfo.Block.TexelSize); // Update the volume texture atlas RHIUpdateTexture3D((const FTexture3DRHIRef&)GetTexture0().ShaderResourceTexture, 0, UpdateRegion, BlockInfo.Block.TexelSize * FormatSize, BlockInfo.Block.TexelSize * BlockInfo.Block.TexelSize * FormatSize, (const uint8*)Texture0Data.GetData()); RHIUpdateTexture3D((const FTexture3DRHIRef&)GetTexture1().ShaderResourceTexture, 0, UpdateRegion, BlockInfo.Block.TexelSize * FormatSize, BlockInfo.Block.TexelSize * BlockInfo.Block.TexelSize * FormatSize, (const uint8*)Texture1Data.GetData()); RHIUpdateTexture3D((const FTexture3DRHIRef&)GetTexture2().ShaderResourceTexture, 0, UpdateRegion, BlockInfo.Block.TexelSize * FormatSize, BlockInfo.Block.TexelSize * BlockInfo.Block.TexelSize * FormatSize, (const uint8*)Texture2Data.GetData()); } else { if (GCacheDrawInterpolationPoints != 0 && DebugDrawingView) { FViewElementPDI DebugPDI(DebugDrawingView, NULL); const FVector WorldPosition = BlockInfo.Block.Min; DebugPDI.DrawPoint(WorldPosition, FLinearColor(0, 0, 1), 10, SDPG_World); } } // Record the position that the sample was taken at BlockInfo.Allocation->TargetPosition = BlockInfo.Block.Min + BlockInfo.Block.Size / 2; BlockInfo.Allocation->TargetSamplePacked0[0] = FVector4(SingleSample.R.V[0], SingleSample.R.V[1], SingleSample.R.V[2], SingleSample.R.V[3]) / PI; BlockInfo.Allocation->TargetSamplePacked0[1] = FVector4(SingleSample.G.V[0], SingleSample.G.V[1], SingleSample.G.V[2], SingleSample.G.V[3]) / PI; BlockInfo.Allocation->TargetSamplePacked0[2] = FVector4(SingleSample.B.V[0], SingleSample.B.V[1], SingleSample.B.V[2], SingleSample.B.V[3]) / PI; BlockInfo.Allocation->TargetSamplePacked1[0] = FVector4(SingleSample.R.V[4], SingleSample.R.V[5], SingleSample.R.V[6], SingleSample.R.V[7]) / PI; BlockInfo.Allocation->TargetSamplePacked1[1] = FVector4(SingleSample.G.V[4], SingleSample.G.V[5], SingleSample.G.V[6], SingleSample.G.V[7]) / PI; BlockInfo.Allocation->TargetSamplePacked1[2] = FVector4(SingleSample.B.V[4], SingleSample.B.V[5], SingleSample.B.V[6], SingleSample.B.V[7]) / PI; BlockInfo.Allocation->TargetSamplePacked2 = FVector4(SingleSample.R.V[8], SingleSample.G.V[8], SingleSample.B.V[8], 0) / PI; BlockInfo.Allocation->TargetDirectionalShadowing = DirectionalShadowing; const float BentNormalLength = SkyBentNormal.Size(); BlockInfo.Allocation->TargetSkyBentNormal = FVector4(SkyBentNormal / FMath::Max(BentNormalLength, .0001f), BentNormalLength); if (!BlockInfo.Allocation->bHasEverUpdatedSingleSample) { // If this is the first update, also set the interpolated state to match the new target //@todo - detect and handle teleports in the same way BlockInfo.Allocation->SingleSamplePosition = BlockInfo.Allocation->TargetPosition; for (int32 VectorIndex = 0; VectorIndex < 3; VectorIndex++) // RGB { BlockInfo.Allocation->SingleSamplePacked0[VectorIndex] = BlockInfo.Allocation->TargetSamplePacked0[VectorIndex]; BlockInfo.Allocation->SingleSamplePacked1[VectorIndex] = BlockInfo.Allocation->TargetSamplePacked1[VectorIndex]; } BlockInfo.Allocation->SingleSamplePacked2 = BlockInfo.Allocation->TargetSamplePacked2; BlockInfo.Allocation->CurrentDirectionalShadowing = BlockInfo.Allocation->TargetDirectionalShadowing; BlockInfo.Allocation->CurrentSkyBentNormal = BlockInfo.Allocation->TargetSkyBentNormal; BlockInfo.Allocation->bHasEverUpdatedSingleSample = true; } BlockInfo.Block.bHasEverBeenUpdated = true; }
void FIndirectLightingCache::UpdateBlock(FScene* Scene, FViewInfo* DebugDrawingView, FBlockUpdateInfo& BlockInfo) { const int32 NumSamplesPerBlock = BlockInfo.Block.TexelSize * BlockInfo.Block.TexelSize * BlockInfo.Block.TexelSize; FSHVectorRGB2 SingleSample; float DirectionalShadowing = 1; if (CanIndirectLightingCacheUseVolumeTexture() && BlockInfo.Allocation->bOpaqueRelevance) { static TArray<float> AccumulatedWeight; AccumulatedWeight.Reset(NumSamplesPerBlock); AccumulatedWeight.AddZeroed(NumSamplesPerBlock); static TArray<FSHVectorRGB2> AccumulatedIncidentRadiance; AccumulatedIncidentRadiance.Reset(NumSamplesPerBlock); AccumulatedIncidentRadiance.AddZeroed(NumSamplesPerBlock); // Interpolate SH samples from precomputed lighting samples and accumulate lighting data for an entire block InterpolateBlock(Scene, BlockInfo.Block, AccumulatedWeight, AccumulatedIncidentRadiance); static TArray<FFloat16Color> Texture0Data; static TArray<FFloat16Color> Texture1Data; static TArray<FFloat16Color> Texture2Data; Texture0Data.Reset(NumSamplesPerBlock); Texture1Data.Reset(NumSamplesPerBlock); Texture2Data.Reset(NumSamplesPerBlock); Texture0Data.AddUninitialized(NumSamplesPerBlock); Texture1Data.AddUninitialized(NumSamplesPerBlock); Texture2Data.AddUninitialized(NumSamplesPerBlock); const int32 FormatSize = GPixelFormats[PF_FloatRGBA].BlockBytes; check(FormatSize == sizeof(FFloat16Color)); // Encode the SH samples into a texture format EncodeBlock(DebugDrawingView, BlockInfo.Block, AccumulatedWeight, AccumulatedIncidentRadiance, Texture0Data, Texture1Data, Texture2Data, SingleSample); // Setup an update region const FUpdateTextureRegion3D UpdateRegion( BlockInfo.Block.MinTexel.X, BlockInfo.Block.MinTexel.Y, BlockInfo.Block.MinTexel.Z, 0, 0, 0, BlockInfo.Block.TexelSize, BlockInfo.Block.TexelSize, BlockInfo.Block.TexelSize); // Update the volume texture atlas RHIUpdateTexture3D((const FTexture3DRHIRef&)GetTexture0().ShaderResourceTexture, 0, UpdateRegion, BlockInfo.Block.TexelSize * FormatSize, BlockInfo.Block.TexelSize * BlockInfo.Block.TexelSize * FormatSize, (const uint8*)Texture0Data.GetData()); RHIUpdateTexture3D((const FTexture3DRHIRef&)GetTexture1().ShaderResourceTexture, 0, UpdateRegion, BlockInfo.Block.TexelSize * FormatSize, BlockInfo.Block.TexelSize * BlockInfo.Block.TexelSize * FormatSize, (const uint8*)Texture1Data.GetData()); RHIUpdateTexture3D((const FTexture3DRHIRef&)GetTexture2().ShaderResourceTexture, 0, UpdateRegion, BlockInfo.Block.TexelSize * FormatSize, BlockInfo.Block.TexelSize * BlockInfo.Block.TexelSize * FormatSize, (const uint8*)Texture2Data.GetData()); } else { InterpolatePoint(Scene, BlockInfo.Block, DirectionalShadowing, SingleSample); } // Record the position that the sample was taken at BlockInfo.Allocation->TargetPosition = BlockInfo.Block.Min + BlockInfo.Block.Size / 2; BlockInfo.Allocation->TargetSamplePacked[0] = FVector4(SingleSample.R.V[0], SingleSample.R.V[1], SingleSample.R.V[2], SingleSample.R.V[3]) / PI; BlockInfo.Allocation->TargetSamplePacked[1] = FVector4(SingleSample.G.V[0], SingleSample.G.V[1], SingleSample.G.V[2], SingleSample.G.V[3]) / PI; BlockInfo.Allocation->TargetSamplePacked[2] = FVector4(SingleSample.B.V[0], SingleSample.B.V[1], SingleSample.B.V[2], SingleSample.B.V[3]) / PI; BlockInfo.Allocation->TargetDirectionalShadowing = DirectionalShadowing; if (!BlockInfo.Allocation->bHasEverUpdatedSingleSample) { // If this is the first update, also set the interpolated state to match the new target //@todo - detect and handle teleports in the same way BlockInfo.Allocation->SingleSamplePosition = BlockInfo.Allocation->TargetPosition; for (int32 VectorIndex = 0; VectorIndex < ARRAY_COUNT(BlockInfo.Allocation->SingleSamplePacked); VectorIndex++) { BlockInfo.Allocation->SingleSamplePacked[VectorIndex] = BlockInfo.Allocation->TargetSamplePacked[VectorIndex]; } BlockInfo.Allocation->CurrentDirectionalShadowing = BlockInfo.Allocation->TargetDirectionalShadowing; BlockInfo.Allocation->bHasEverUpdatedSingleSample = true; } BlockInfo.Block.bHasEverBeenUpdated = true; }
IOHIDTableAcceleration * IOHIDTableAcceleration::CreateOriginalWithTable (CFDataRef table, double acceleration, const double resolution, const double rate) { double scale; UInt32 count; Boolean isLower; ACCEL_POINT lower, upper, p1, p2, p3, prev, curveP1, curveP2; double loAccel, hiAccel; const void * loTable = NULL; const void * hiTable = NULL; unsigned int loCount, hiCount; p1 = prev = curveP1 = curveP2 = {0,0}; loCount = hiCount = 0; loAccel = 0; if( table == NULL || resolution == 0 || rate == 0) { return NULL; } IOHIDTableAcceleration * self = new IOHIDTableAcceleration; if (self == NULL) { return NULL; } self->resolution_ = resolution; self->rate_ = rate; hiTable = CFDataGetBytePtr(table); scale = FIXED_TO_DOUBLE(ACCEL_TABLE_CONSUME_INT32(&hiTable)); ACCEL_TABLE_CONSUME_INT32(&hiTable); // normalize table's default (scale) to 0.5 if( acceleration > 0.5) { acceleration = (acceleration - 0.5) * (1 - scale ) * 2 + scale ; } else { acceleration = acceleration * scale ; } count = ACCEL_TABLE_CONSUME_INT16(&hiTable); scale = 1.0; // find curves bracketing the desired value do { hiAccel = FIXED_TO_DOUBLE(ACCEL_TABLE_CONSUME_INT32(&hiTable)); hiCount = ACCEL_TABLE_CONSUME_INT16 (&hiTable); if( acceleration <= hiAccel) { break; } if( 0 == --count) { // this much over the highest table scale = (hiAccel) ? (acceleration / hiAccel ) : 0; loTable = NULL; break; } loTable = hiTable; loAccel = hiAccel; loCount = hiCount; hiTable = (uint8_t*)hiTable + loCount * 8; } while (true); // scale between the two if( loTable) { scale = (hiAccel == loAccel) ? 0 : (acceleration - loAccel) / (hiAccel - loAccel); } // or take all the high one else { loTable = hiTable; //loAccel = hiAccel; loCount = 0; } lower = ACCELL_TABLE_CONSUME_POINT(&loTable); upper = ACCELL_TABLE_CONSUME_POINT(&hiTable); do { // consume next point from first X isLower = (loCount && (!hiCount || (lower.x <= upper.x))); if( isLower) { /* highline */ p2 = upper; p3 = lower; if( loCount && (--loCount)) { lower = ACCELL_TABLE_CONSUME_POINT(&loTable); } } else { /* lowline */ p2 = lower; p3 = upper; if( hiCount && (--hiCount)) { upper = ACCELL_TABLE_CONSUME_POINT(&hiTable); } } { curveP2 = InterpolatePoint(p3, p1, p2 , scale, isLower); curveP2.x *= (resolution/rate); curveP2.y *= kCursorScale; ACCEL_SEGMENT segment; segment.m = (curveP2.x == curveP1.x) ? 0 : (curveP2.y - curveP1.y) / (curveP2.x - curveP1.x), segment.b = curveP2.y - segment.m * curveP2.x, segment.x = (loCount || hiCount) ? curveP2.x : MAX_DEVICE_THRESHOLD; self->segments_.push_back ({ segment }); curveP1 = curveP2; } // continue on from last point if( loCount && hiCount) { if( lower.x > upper.x) { prev = p1; } else { prev = p1; p1 = p3; } } else { p2 = p1; p1 = prev; prev = p2; } } while( loCount || hiCount ); return self; }