//here we go, thats the method called by vvvv each frame //all data handling should be in here public void Evaluate(int SpreadMax) { //if any of the inputs has changed //recompute the outputs if (FMyValueInput1.PinIsChanged || FMyValueInput2.PinIsChanged || FMyValueInput3.PinIsChanged || FMyValueInput4.PinIsChanged) { //first set slicecounts for all outputs //the incoming int SpreadMax is the maximum slicecount of all input pins, which is a good default FMyValueOutput1.SliceCount = SpreadMax; FMyValueOutput2.SliceCount = SpreadMax; //the variables to fill with the input data double a1, a2, a3, a4; double b1, b2, b3, b4; double c1, c2, c3, c4; double d1, d2, d3, d4; Vector4D a, b, c, d, out1, out2; //loop for all slices for (int i = 0; i < SpreadMax; i++) { //read data from inputs FMyValueInput1.GetValue4D(i, out a1, out a2, out a3, out a4); FMyValueInput2.GetValue4D(i, out b1, out b2, out b3, out b4); FMyValueInput3.GetValue4D(i, out c1, out c2, out c3, out c4); FMyValueInput4.GetValue4D(i, out d1, out d2, out d3, out d4); a = new Vector4D(a1, a2, a3, a4); b = new Vector4D(b1, b2, b3, b4); c = new Vector4D(c1, c2, c3, c4); d = new Vector4D(d1, d2, d3, d4); // http://en.wikipedia.org/wiki/Octonion // following the Cayley-Dickinson construction // (a,b)(c,d) = (ac - db * ,da + bc * ) // where x * is the conjugate of x out1 = new Vector4D(b1, -b2, -b3, -b4); out2 = new Vector4D(c1, -c2, -c3, -c4); out1 = a * c - d * out1; out2 = d * a + b * out2; //write data to outputs FMyValueOutput1.SetValue4D(i, out1.x, out1.y, out1.z, out1.w); FMyValueOutput2.SetValue4D(i, out2.x, out2.y, out2.z, out2.w); } } #endregion mainloop }
//here we go, thats the method called by vvvv each frame //all data handling should be in here public void Evaluate(int SpreadMax) { FMyMeshOutput.SliceCount = SpreadMax; // by now, this node is not spreadable so it should always be 1. if (Radius.PinIsChanged || Perspective.PinIsChanged || QuaternionTransform.PinIsChanged) { Radius.GetValue(0, out radius); Perspective.GetValue(0, out p); QuaternionTransform.GetValue4D(0, out a, out b, out c, out d); FDeviceMeshes.Clear(); } }
//here we go, thats the method called by vvvv each frame //all data handling should be in here public void Evaluate(int SpreadMax) { //if any of the inputs has changed //recompute the outputs if (FMyValueInput1.PinIsChanged || FMyValueInput2.PinIsChanged || FMyValueInput3.PinIsChanged || FMyValueInput4.PinIsChanged) { //first set slicecounts for all outputs //the incoming int SpreadMax is the maximum slicecount of all input pins, which is a good default FMyValueOutput1.SliceCount = SpreadMax; FMyValueOutput2.SliceCount = SpreadMax; //the variables to fill with the input data double a1, a2, a3, a4; double b1, b2, b3, b4; double c1, c2, c3, c4; double d1, d2, d3, d4; Vector4D a, b, c, d, out1, out2; //loop for all slices for (int i = 0; i < SpreadMax; i++) { //read data from inputs FMyValueInput1.GetValue4D(i, out a1, out a2, out a3, out a4); FMyValueInput2.GetValue4D(i, out b1, out b2, out b3, out b4); FMyValueInput3.GetValue4D(i, out c1, out c2, out c3, out c4); FMyValueInput4.GetValue4D(i, out d1, out d2, out d3, out d4); a = new Vector4D(a1, a2, a3, a4); b = new Vector4D(b1, b2, b3, b4); // create c and d already inverted, then just use the same algorithm as multiplication c = new Vector4D(c1, -c2, -c3, -c4) / (c1 * c1 + c2 * c2 + c3 * c3 + c4 * c4 + d1 * d1 + d2 * d2 + d3 * d3 + d4 * d4); d = new Vector4D(-d1, -d2, -d3, -d4) / (c1 * c1 + c2 * c2 + c3 * c3 + c4 * c4 + d1 * d1 + d2 * d2 + d3 * d3 + d4 * d4); out1 = new Vector4D(b.x, -b.y, -b.z, -b.w); out2 = new Vector4D(c.x, -c.y, -c.z, -c.w); out1 = a * c - d * out1; out2 = d * a + b * out2; //write data to outputs FMyValueOutput1.SetValue4D(i, out1.x, out1.y, out1.z, out1.w); FMyValueOutput2.SetValue4D(i, out2.x, out2.y, out2.z, out2.w); } } #endregion mainloop }
//here we go, thats the method called by vvvv each frame //all data handling should be in here public void Evaluate(int SpreadMax) { //if any of the inputs has changed //recompute the outputs if (FDistortion.PinIsChanged || FFocalLength.PinIsChanged || FPrincipalPoint.PinIsChanged || FResolution.PinIsChanged) { //get the distortion values FDistortion.GetValue4D(0, out FDist.x, out FDist.y, out FDist.z, out FDist.w); FFocalLength.GetValue2D(0, out FFocal.x, out FFocal.y); FPrincipalPoint.GetValue2D(0, out FPrincipal.x, out FPrincipal.y); FResolution.GetValue2D(0, out FReso.x, out FReso.y); } //set slicecounts for output //here its the same as the input SpreadMax = FInput.SliceCount; FOutput.SliceCount = SpreadMax; FTries.SliceCount = SpreadMax; //the variable to fill with the input data Vector2D currentPosition; //loop for all slices for (int i = 0; i < SpreadMax; i++) { //read data from inputs FInput.GetValue2D(i, out currentPosition.x, out currentPosition.y); int tries; //function per slice currentPosition = Undistort(currentPosition, FFocal, FPrincipal, FDist, FReso, out tries); //write data to outputs FOutput.SetValue2D(i, currentPosition.x, currentPosition.y); FTries.SetValue(i, tries); } }
//here we go, thats the method called by vvvv each frame //all data handling should be in here public void Evaluate(int SpreadMax) { //if any of the inputs has changed //recompute the outputs if (FPositionInput.PinIsChanged || FOctavesInput.PinIsChanged || FFrequencyInput.PinIsChanged || FPersistanceInput.PinIsChanged) { //first set slicecounts for all outputs //the incoming int SpreadMax is the maximum slicecount of all input pins, which is a good default FOutput.SliceCount = SpreadMax; double octaves, freq, pers; FOctavesInput.GetValue(0, out octaves); FFrequencyInput.GetValue(0, out freq); FPersistanceInput.GetValue(0, out pers); //the variable to fill with the input position Vector4D pos; //loop for all slices for (int i = 0; i < SpreadMax; i++) { //read position from inputs FPositionInput.GetValue4D(i, out pos.x, out pos.y, out pos.z, out pos.w); //noise function per slice double noiseVal = 0; for (int o = 0; o <= (int)octaves; o++) { double comul = Math.Pow(freq, o); noiseVal += SimplexNoise.noise(pos.x * comul, pos.y * comul, pos.z * comul, pos.w * comul) * Math.Pow(pers, o); } //write data to outputs FOutput.SetValue(i, noiseVal); } } }
//here we go, thats the method called by vvvv each frame //all data handling should be in here public void Evaluate(int SpreadMax) { //if any of the inputs has changed //recompute the outputs if (FTransformInput.PinIsChanged || FP1Input.PinIsChanged || FP2Input.PinIsChanged || FP3Input.PinIsChanged || FP4Input.PinIsChanged) { //first set slicecounts for all outputs //the incoming int SpreadMax is the maximum slicecount of all input pins, which is a good default FTransformOutput.SliceCount = SpreadMax; //the variables to fill with the input data Matrix4x4 matrixSlice; Vector4D p1Slice; Vector4D p2Slice; Vector4D p3Slice; Vector4D p4Slice; //loop for all slices for (int i = 0; i < SpreadMax; i++) { //read data from inputs FTransformInput.GetMatrix(i, out matrixSlice); FP1Input.GetValue4D(i, out p1Slice.x, out p1Slice.y, out p1Slice.z, out p1Slice.w); FP2Input.GetValue4D(i, out p2Slice.x, out p2Slice.y, out p2Slice.z, out p2Slice.w); FP3Input.GetValue4D(i, out p3Slice.x, out p3Slice.y, out p3Slice.z, out p3Slice.w); FP4Input.GetValue4D(i, out p4Slice.x, out p4Slice.y, out p4Slice.z, out p4Slice.w); //function per slice matrixSlice = VMath.BilerpMatrix(p1Slice, p2Slice, p4Slice, p3Slice) * matrixSlice; //write data to outputs FTransformOutput.SetMatrix(i, matrixSlice); } } }
//here we go, thats the method called by vvvv each frame //all data handling should be in here public void Evaluate(int SpreadMax) { //if size changed if (FSizeInput.PinIsChanged || FResetInput.PinIsChanged) { //get the size double pinValue; FSizeInput.GetValue(0, out pinValue); FSizeX = Math.Max((int)Math.Round(pinValue), 1); FSizeInput.GetValue(1, out pinValue); FSizeY = Math.Max((int)Math.Round(pinValue), 1); FSizeInput.GetValue(2, out pinValue); FSizeZ = Math.Max((int)Math.Round(pinValue), 1); FSize = FSizeX * FSizeY * FSizeZ; SpreadMax = FSize; FMyVectorOutput.SliceCount = SpreadMax; //get mem for the arrays FCurrentState = new float[SpreadMax]; FLastState = new float[SpreadMax]; FBeforeLastState = new float[SpreadMax]; //init the arrays for (int i = 0; i < SpreadMax; i++) { FCurrentState[i] = 0; FLastState[i] = 0; FBeforeLastState[i] = 0; } } //shall we render? double val; FRenderInput.GetValue(0, out val); if (val < 0.5) { return; } //get other parameters if (FNrOfThreadsInput.PinIsChanged || FAttackInput.PinIsChanged || FDecayInput.PinIsChanged) { //get number of threads double pinValue; FNrOfThreadsInput.GetValue(0, out pinValue); FThreadCount = Math.Max((int)Math.Round(pinValue), 1); FAttackInput.GetValue(0, out pinValue); FAttack = pinValue; FDecayInput.GetValue(0, out pinValue); FDecay = 1 - pinValue; } //the variables to fill with the input data Vector4D externalPressure; //read data from inputs FExternalPressureInput.GetValue4D(0, out externalPressure.x, out externalPressure.y, out externalPressure.z, out externalPressure.w); //calc how many slices one thread should process int divCount = Math.Max(FSize / FThreadCount, 1); //how many will be left (if threadCount is not a divisor of SpreadMax) int divRemainder = Math.Max(FSize - divCount * FThreadCount, 0); //array of the threads Thread[] threadArray = new Thread[FThreadCount]; //create all threads to calc the function //pack up the parameter object and start them for (int i = 0; i < FThreadCount; i++) { //pass the function as entry point to the thread threadArray[i] = new Thread(CalcPressure); //if not last slice if (i < (FThreadCount - 1)) { //start the thread for the defined range //we pass the following data as an object array (which is an object): //(input vectors, the array for the result, start index, length of range) threadArray[i].Start(new object[] { externalPressure, i * divCount, divCount }); } else { //start for the last slice range threadArray[i].Start(new object[] { externalPressure, i * divCount, divCount + divRemainder }); } } //wait for all threads, important to stay in sync with the mainloop for (int i = 0; i < FThreadCount; i++) { threadArray[i].Join(); } for (int i = 0; i < FSize; i++) { //write data to outputs FMyVectorOutput.SetValue(i, FCurrentState[i]); } //swap data float[] temp1, temp2; temp1 = FLastState; temp2 = FBeforeLastState; FLastState = FCurrentState; FBeforeLastState = temp1; FCurrentState = temp2; }