public Game() { // ResourceLoader.loadMesh("Gemstone.obj");//new Mesh(); _material = new Material(new Texture("test.png"), new Vector3f(1, 1, 1), 1, 8); _shader = PhongShader.getInstance(); _camera = new Camera(); _transform = new Transform(); float fieldDepth = 10.0f; float fieldWidth = 10.0f; Vertex[] vertices = new Vertex[] { new Vertex(new Vector3f(-fieldWidth, 0.0f, -fieldDepth), new Vector2f(0.0f, 0.0f)), new Vertex(new Vector3f(-fieldWidth, 0.0f, fieldDepth * 3), new Vector2f(0.0f, 1.0f)), new Vertex(new Vector3f(fieldWidth * 3, 0.0f, -fieldDepth), new Vector2f(1.0f, 0.0f)), new Vertex(new Vector3f(fieldWidth * 3, 0.0f, fieldDepth * 3), new Vector2f(1.0f, 1.0f)) }; int indices[] = {0, 1, 2, 2, 1, 3}; _mesh = new Mesh(vertices, indices, true); Transform.setProjection(70f, MainWindow.getWidth(), MainWindow.getHeight(), 0.1f, 1000f); Transform.setCamera(_camera); PhongShader.setAmbientLight(new Vector3f(0.1f, 0.1f, 0.1f)); PhongShader.setDirectionalLight( new DirectionalLight(new BaseLight(new Vector3f(1, 1, 1), 0.01f), new Vector3f(1, 1, 1))); PhongShader.setPointLight(new PointLight[] {pLight1, pLight2, pLight3}); PhongShader.setSpotLights(new SpotLight[] {sLight1}); }
@Test public void movingRunOutOfPointsBeforeHittingwindow() { Transform movingTransform = new MetricMappingTransform(new MovingValueMapping()); Map<Long, String> datapoints = new HashMap<Long, String>(); datapoints.put(0L, "3.0"); datapoints.put(60000L, "6.0"); datapoints.put(120000L, "9.0"); Map<Long, String> actual = new HashMap<Long, String>(); actual.put(0L, "3.0"); actual.put(60000L, "4.5"); actual.put(120000L, "7.5"); Metric metric = new Metric(TEST_SCOPE, TEST_METRIC); metric.setDatapoints(datapoints); List<Metric> metrics = new ArrayList<Metric>(); metrics.add(metric); List<String> constants = new ArrayList<String>(1); constants.add("120s"); constants.add("avg"); List<Metric> result = movingTransform.transform(metrics, constants); assertEquals(result.get(0).getDatapoints().size(), 3); assertEquals(result.get(0).getDatapoints(), actual); }
/** * Return gradient term of quadratic. This instance will be in the vector space of the * perturbModel, if provided. Otherwise, uses an instance of the referenceModel. * * @return Value of <code> b = -F' N [data - f(m)] + Mm </code> if dampOnlyPerturbation is false, * and <code> b = -F' N [data - f(m)] </code> if dampOnlyPerturbation is true. */ public Vect getB() { Vect data = VectUtil.cloneZero(_data); // data is data with zeros _transform.forwardNonlinear(data, _referenceModel); // data is f(m) data.add(1., -1., _data); // data is -e = -(d - f(m)) _transform.adjustRobustErrors(data); // (remove outliers from e) data.multiplyInverseCovariance(); // data is -Ne Vect b = null; if (_dampOnlyPerturbation) { if (_perturbModel != null) { b = VectUtil.cloneZero(_perturbModel); // b is 0 } else { b = VectUtil.cloneZero(_referenceModel); // b is 0 } } else { if (_perturbModel != null) { b = _perturbModel.clone(); b.project(0., 1., _referenceModel); // b is m } else { b = _referenceModel.clone(); // b is m } b.multiplyInverseCovariance(); // b is M m } _transform.addTranspose(data, b, _referenceModel); // b is -F'Ne [+ Mm] data.dispose(); return b; }
/* (non-Javadoc) * @see org.dyn4j.geometry.Shape#createAABB(org.dyn4j.geometry.Transform) */ @Override public AABB createAABB(Transform transform) { double vx = 0.0; double vy = 0.0; // get the first point Vector2 p = transform.getTransformed(this.vertices[0]); // project the point onto the vector double minX = Vector2.X_AXIS.dot(p); double maxX = minX; double minY = Vector2.Y_AXIS.dot(p); double maxY = minY; // loop over the rest of the vertices int size = this.vertices.length; for (int i = 1; i < size; i++) { // get the next point p = transform.getTransformed(this.vertices[i]); // project it onto the vector vx = Vector2.X_AXIS.dot(p); vy = Vector2.Y_AXIS.dot(p); // compare the x values minX = Math.min(minX, vx); maxX = Math.max(maxX, vx); minY = Math.min(minY, vy); maxY = Math.max(maxY, vy); } // create the aabb return new AABB(minX, minY, maxX, maxY); }
@Test public void testJoinTransformWithOneMetric() { Transform joinTransform = new JoinTransform(); Map<Long, String> datapoints_1 = new HashMap<Long, String>(); datapoints_1.put(1000L, "1"); datapoints_1.put(2000L, "2"); datapoints_1.put(3000L, "3"); Metric metric_1 = new Metric(TEST_SCOPE, TEST_METRIC); metric_1.setDatapoints(datapoints_1); List<Metric> metrics = new ArrayList<Metric>(); metrics.add(metric_1); Map<Long, String> expected = new HashMap<Long, String>(); expected.put(1000L, "1"); expected.put(2000L, "2"); expected.put(3000L, "3"); List<Metric> result = joinTransform.transform(metrics); assertEquals(result.get(0).getDatapoints().size(), 3); assertEquals(expected, result.get(0).getDatapoints()); }
/* (non-Javadoc) * @see org.dyn4j.geometry.Convex#getFarthestPoint(org.dyn4j.geometry.Vector, org.dyn4j.geometry.Transform) */ @Override public Vector2 getFarthestPoint(Vector2 n, Transform transform) { // transform the normal into local space Vector2 localn = transform.getInverseTransformedR(n); Vector2 point = new Vector2(); // set the farthest point to the first one point.set(this.vertices[0]); // prime the projection amount double max = localn.dot(this.vertices[0]); // loop through the rest of the vertices to find a further point along the axis int size = this.vertices.length; for (int i = 1; i < size; i++) { // get the current vertex Vector2 v = this.vertices[i]; // project the vertex onto the axis double projection = localn.dot(v); // check to see if the projection is greater than the last if (projection > max) { // otherwise this point is the farthest so far so clear the array and add it point.set(v); // set the new maximum max = projection; } } // transform the point into world space transform.transform(point); return point; }
private static void loadTransformable(Transformable transformable) throws IOException { loadObject3D(transformable); if (readBoolean()) // hasComponentTransform { float tx = readFloat(); float ty = readFloat(); float tz = readFloat(); transformable.setTranslation(tx, ty, tz); float sx = readFloat(); float sy = readFloat(); float sz = readFloat(); transformable.setScale(sx, sy, sz); float angle = readFloat(); float ax = readFloat(); float ay = readFloat(); float az = readFloat(); transformable.setOrientation(angle, ax, ay, az); } if (readBoolean()) // hasGeneralTransform { Transform t = new Transform(); t.set(readMatrix()); transformable.setTransform(t); } }
@Test public void movingWithOnlyOnePoint() { Transform movingTransform = new MetricMappingTransform(new MovingValueMapping()); Map<Long, String> datapoints = new HashMap<Long, String>(); datapoints.put(0L, "3.0"); Map<Long, String> actual = new HashMap<Long, String>(); actual.put(0L, "3.0"); Metric metric = new Metric(TEST_SCOPE, TEST_METRIC); metric.setDatapoints(datapoints); List<Metric> metrics = new ArrayList<Metric>(); metrics.add(metric); List<String> constants = new ArrayList<String>(1); constants.add("120s"); constants.add("avg"); List<Metric> result = movingTransform.transform(metrics, constants); assertEquals(result.get(0).getDatapoints().size(), 1); assertEquals(result.get(0).getDatapoints(), actual); }
@Test public void testNonSquareMatrix() { int[][] testInput = { {6, 0, 5}, {0, 1, 1}, {1, 5, 0}, {0, 1, 0}, {1, 5, 7}, {1, 1, 1} }; double[][] testOutput = {{}}; double error = .00001; Matrix inputMatrix = new YaleSparseMatrix(6, 3); for (int row = 0; row < 6; ++row) for (int col = 0; col < 3; ++col) inputMatrix.set(row, col, testInput[row][col]); Transform transform = new TfIdfTransform(); Matrix outputMatrix = transform.transform(inputMatrix); for (int row = 0; row < 6; ++row) { for (int col = 0; col < 3; ++col) System.out.println(outputMatrix.get(row, col)); // assertEquals(testOutput[row][col], // outputMatrix.get(row, col), error); } }
/** * Recursively transform a BSP-tree from a sub-hyperplane. * * @param node current BSP tree node * @param transformed image of the instance hyperplane by the transform * @param transform transform to apply * @return a new tree */ private BSPTree<T> recurseTransform( final BSPTree<T> node, final Hyperplane<S> transformed, final Transform<S, T> transform) { if (node.getCut() == null) { return new BSPTree<T>(node.getAttribute()); } @SuppressWarnings("unchecked") BoundaryAttribute<T> attribute = (BoundaryAttribute<T>) node.getAttribute(); if (attribute != null) { final SubHyperplane<T> tPO = (attribute.getPlusOutside() == null) ? null : transform.apply(attribute.getPlusOutside(), hyperplane, transformed); final SubHyperplane<T> tPI = (attribute.getPlusInside() == null) ? null : transform.apply(attribute.getPlusInside(), hyperplane, transformed); attribute = new BoundaryAttribute<T>(tPO, tPI); } return new BSPTree<T>( transform.apply(node.getCut(), hyperplane, transformed), recurseTransform(node.getPlus(), transformed, transform), recurseTransform(node.getMinus(), transformed, transform), attribute); }
public void render() { RenderUtil.setClearColor(Transform.getCamera().getPos().div(2048f).abs()); _shader.bind(); _shader.updateUniforms( _transform.getTransformation(), _transform.getProjectedTransformation(), _material); _mesh.draw(); }
/** * Multiply by Hessian <code> H = F'NF + M </code> * * @param x Vector to be multiplied and modified */ public void multiplyHessian(Vect x) { Vect data = _data.clone(); _transform.forwardLinearized(data, x, _referenceModel); // data is Fx data.multiplyInverseCovariance(); // data is NFx x.multiplyInverseCovariance(); // x is Mx _transform.addTranspose(data, x, _referenceModel); // x is (F'NF +M)x data.dispose(); }
@Test(expected = UnsupportedOperationException.class) public void testJoinTransformWithConstant() { Transform joinTransform = new JoinTransform(); List<Metric> metrics = new ArrayList<Metric>(); List<String> constants = new ArrayList<String>(); joinTransform.transform(metrics, constants); }
@Test public void testEmptyFeatureVector() { Config config = ConfigFactory.parseString(makeConfig()); Transform transform = TransformFactory.createTransform(config, "test_cut"); FeatureVector featureVector = new FeatureVector(); transform.doTransform(featureVector); assertTrue(featureVector.getStringFeatures() == null); }
@Test public void testJoinTransformWithEmptyMetricsLists() { Transform joinTransform = new JoinTransform(); List<Metric> metrics_1 = new ArrayList<Metric>(); List<Metric> metrics_2 = new ArrayList<Metric>(); List<Metric> result = joinTransform.transform(metrics_1, metrics_2); assertEquals(result.size(), 0); }
@Test(expected = UnsupportedOperationException.class) public void transform_ShouldThrowUnsupportedOperationExceptionWhenNoWindowSizeSpecified() { List<Metric> metrics = new ArrayList<Metric>(); metrics.add(new Metric(TEST_SCOPE, TEST_METRIC)); Transform movingTransform = new MetricMappingTransform(new MovingValueMapping()); movingTransform.transform(metrics); }
public Graph transpose() { Graph g = copy(); try { g.graph = Transform.transposeOffline(g.graph, 1000); g.reverse = Transform.transposeOffline(g.reverse, 1000); } catch (IOException ex) { throw new Error(ex); } return g; }
@Test(expected = UnsupportedOperationException.class) public void transform_ShouldThrowUnsupportedOperationExceptionWhenTypeIsInvalid() { List<Metric> metrics = new ArrayList<Metric>(); metrics.add(new Metric(TEST_SCOPE, TEST_METRIC)); Transform movingTransform = new MetricMappingTransform(new MovingValueMapping()); List<String> constants = new ArrayList<String>(); constants.add("2"); constants.add("foobar"); movingTransform.transform(metrics); }
@Test public void testTranslateThenScale() { transform.addTransformation("translate 2 1"); transform.addTransformation( "scale 2"); // KOMMENTAR: LUKAS KELLER: Mehrere Befehle hintereinander ausführen können: // d.h. mit Stack arbeiten transform .getAffineTransform() .transform( new Point2D.Double(2, 3), target); // KOMMENTAR: LUKAS KELLER: Hier wird Transformation durchgeführt assertTrue(target.distance(new Point2D.Double(8, 8)) < 0.001); }
/* (non-Javadoc) * @see org.dyn4j.geometry.Convex#getAxes(java.util.List, org.dyn4j.geometry.Transform) */ @Override public Vector2[] getAxes(Vector2[] foci, Transform transform) { // get the size of the foci list int fociSize = foci != null ? foci.length : 0; // get the number of vertices this polygon has int size = this.vertices.length; // the axes of a polygon are created from the normal of the edges // plus the closest point to each focus Vector2[] axes = new Vector2[size + fociSize]; int n = 0; // loop over the edge normals and put them into world space for (int i = 0; i < size; i++) { // create references to the current points Vector2 v = this.normals[i]; // transform it into world space and add it to the list axes[n++] = transform.getTransformedR(v); } // loop over the focal points and find the closest // points on the polygon to the focal points for (int i = 0; i < fociSize; i++) { // get the current focus Vector2 f = foci[i]; // create a place for the closest point Vector2 closest = transform.getTransformed(this.vertices[0]); double d = f.distanceSquared(closest); // find the minimum distance vertex for (int j = 1; j < size; j++) { // get the vertex Vector2 p = this.vertices[j]; // transform it into world space p = transform.getTransformed(p); // get the squared distance to the focus double dt = f.distanceSquared(p); // compare with the last distance if (dt < d) { // if its closer then save it closest = p; d = dt; } } // once we have found the closest point create // a vector from the focal point to the point Vector2 axis = f.to(closest); // normalize it axis.normalize(); // add it to the array axes[n++] = axis; } // return all the axes return axes; }
public void delete() throws ParserConfigurationException, SAXException, IOException, TransformerException { Document document = new GetDocument().getDocument(); Element rootElement = document.getDocumentElement(); NodeList contacts = rootElement.getChildNodes(); System.out.println("Enter the name of the contact to delete: "); BufferedReader inItem = new BufferedReader(new InputStreamReader(System.in)); String contactToDelete = inItem.readLine(); boolean isContactFound = false; for (int i = 0; i < contacts.getLength(); i++) { Node contact = contacts.item(i); NodeList contactData = contact.getChildNodes(); for (int j = 0; j < contactData.getLength(); j++) { Node dataNode = contactData.item(j); if (dataNode.getNodeName().equals("name") && dataNode.getTextContent().equals(contactToDelete)) { contact.getParentNode().removeChild(contact); isContactFound = true; System.out.println("The contact " + contactToDelete + " has been deleted."); } } } Transform.transform(document); if (!isContactFound) System.out.println("No such contact found."); }
/* (non-Javadoc) * @see org.dyn4j.geometry.Shape#contains(org.dyn4j.geometry.Vector, org.dyn4j.geometry.Transform) */ @Override public boolean contains(Vector2 point, Transform transform) { // if the polygon is convex then do a simple inside test // if the the sign of the location of the point on the side of an edge (or line) // is always the same and the polygon is convex then we know that the // point lies inside the polygon // This method doesn't care about vertex winding // inverse transform the point to put it in local coordinates Vector2 p = transform.getInverseTransformed(point); Vector2 p1 = this.vertices[0]; Vector2 p2 = this.vertices[1]; // get the location of the point relative to the first two vertices double last = Segment.getLocation(p, p1, p2); int size = this.vertices.length; // loop through the rest of the vertices for (int i = 1; i < size; i++) { // p1 is now p2 p1 = p2; // p2 is the next point p2 = this.vertices[(i + 1) == size ? 0 : i + 1]; // check if they are equal (one of the vertices) if (p.equals(p1)) { return true; } // do side of line test // multiply the last location with this location // if they are the same sign then the opertation will yield a positive result // -x * -y = +xy, x * y = +xy, -x * y = -xy, x * -y = -xy if (last * Segment.getLocation(p, p1, p2) < 0) { return false; } } return true; }
public static void reshape(int w, int h) { GLES20.glViewport(0, 0, w, h); aspectRatio = (float) w / h; float[] mProjection = new float[16]; Matrix.frustumM(mProjection, 0, -aspectRatio, aspectRatio, -1.0f, 1.0f, 1, 1000); Transform.setProjection(mProjection); }
/** * Converts a list of one type into a list of another type. * * @param xs The list to convert. * @param t How to transform each element. * @return A new list of type Y. */ public static <X, Y> List<Y> map(List<X> xs, Transform<X, Y> t) { List<Y> ys = new ArrayList<Y>(); for (X x : xs) { ys.add(t.transform(x)); } return ys; }
@Test public void testTransformLowerBoundOnly() { Config config = ConfigFactory.parseString(makeConfigWithLowerBoundOnly()); Transform transform = TransformFactory.createTransform(config, "test_cut"); FeatureVector featureVector = TransformTestingHelper.makeFeatureVector(); transform.doTransform(featureVector); Map<String, Set<String>> stringFeatures = featureVector.getStringFeatures(); assertTrue(stringFeatures.size() == 1); Map<String, Double> feat1 = featureVector.getFloatFeatures().get("loc"); assertEquals(2, feat1.size()); assertEquals(37.7, feat1.get("lat"), 0.1); assertEquals(40.0, feat1.get("long"), 0.1); assertNull(feat1.get("z")); }
/* (non-Javadoc) * @see org.dyn4j.geometry.Convex#getFarthestFeature(org.dyn4j.geometry.Vector, org.dyn4j.geometry.Transform) */ @Override public Edge getFarthestFeature(Vector2 n, Transform transform) { // transform the normal into local space Vector2 localn = transform.getInverseTransformedR(n); Vector2 maximum = new Vector2(); double max = -Double.MAX_VALUE; int index = 0; // find the vertex on the polygon that is further along on the penetration axis int count = this.vertices.length; for (int i = 0; i < count; i++) { // get the current vertex Vector2 v = this.vertices[i]; // get the scalar projection of v onto axis double projection = localn.dot(v); // keep the maximum projection point if (projection > max) { // set the max point maximum.set(v); // set the new maximum max = projection; // save the index index = i; } } // once we have the point of maximum // see which edge is most perpendicular int l = index + 1 == count ? 0 : index + 1; int r = index - 1 < 0 ? count - 1 : index - 1; Vector2 leftN = this.normals[index == 0 ? count - 1 : index - 1]; Vector2 rightN = this.normals[index]; // create the maximum point for the feature (transform the maximum into world space) transform.transform(maximum); Vertex vm = new Vertex(maximum, index); // is the left or right edge more perpendicular? if (leftN.dot(localn) < rightN.dot(localn)) { Vector2 left = transform.getTransformed(this.vertices[l]); Vertex vl = new Vertex(left, l); // make sure the edge is the right winding return new Edge(vm, vl, vm, maximum.to(left), index + 1); } else { Vector2 right = transform.getTransformed(this.vertices[r]); Vertex vr = new Vertex(right, r); // make sure the edge is the right winding return new Edge(vr, vm, vm, right.to(maximum), index); } }
private void updateTransform() { if (transformNeedsUpdate) { nativeGetTransform(IntercomHelper.getBuffer()); transformCache = IntercomHelper.decodeTransform(); inverseTransformCache = transformCache.getInverse(); transformNeedsUpdate = false; } }
/** * SQL数据查询,按ResultSet的列定义转换并返回Table,支持分页。应从前端传入完整列定义(Baas.getDataColumns( data)), * 以解决oracle等数据库不区分date、time、datetime,导致的数据格式转换问题;兼容了以前只传入列名字符串(data. getColumnIDs())的写法,但是已不再推荐。 * * @param conn * @param sql * @param params SQL中问号对应的参数值,按顺序匹配 * @param columns 列定义 * @param offset 偏移行,null则不分页 * @param limit 行数,null则不分页 * @return * @throws SQLException */ public static Table queryData( Connection conn, String sql, List<Object> params, Object columns, Integer offset, Integer limit) throws SQLException { if (limit != null && offset != null) { if (isMysql(conn)) { sql += " LIMIT " + offset + "," + limit; } else if (isOracle(conn)) { sql = String.format( "SELECT * FROM (SELECT rownum no___, A___.* FROM (%s) A___ WHERE rownum <= %d) WHERE no___ > %d", sql, offset + limit, offset); } } // System.out.println(sql); PreparedStatement pstat = conn.prepareStatement(sql); try { if (params != null) { for (int i = 0, len = params.size(); i < len; i++) { pstat.setObject(i + 1, params.get(i)); } } ResultSet rs = pstat.executeQuery(); if (limit != null && offset != null && !isMysql(conn) && !isOracle(conn)) { for (int i = 0; i < offset; i++) { rs.next(); } } Table table = null; if (columns instanceof JSONObject) { table = Transform.createTableByColumnsDefine((JSONObject) columns); } else { table = Transform.createTableByResultSet(rs, (String) columns); } Transform.loadRowsFromResultSet(table, rs, limit); return table; } finally { pstat.close(); } }
@Test public void testMatrixTransformSize() { int[][] testInput = { {0, 0, 0, 0, 1, 1, 2, 4, 5, 0}, {0, 1, 1, 2, 0, 1, 5, 2, 8, 10}, {1, 5, 0, 0, 1, 0, 6, 3, 7, 9}, {0, 1, 0, 1, 0, 1, 2, 0, 3, 0}, {1, 5, 7, 0, 0, 1, 6, 10, 2, 45}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1} }; double[][] testOutput = { { 0.00000, 0.00000, 0.00000, 0.00000, 0.17028, 0.10217, 0.04644, 0.10217, 0.09824, 0.00000, }, { 0.00000, 0.00810, 0.01171, 0.05268, 0.00000, 0.02107, 0.02395, 0.01054, 0.03242, 0.01621, }, { 0.07438, 0.08582, 0.00000, 0.00000, 0.07438, 0.00000, 0.06086, 0.03347, 0.06008, 0.03090, }, { 0.00000, 0.03929, 0.00000, 0.12771, 0.00000, 0.10217, 0.04644, 0.00000, 0.05894, 0.00000, }, { 0.03512, 0.04052, 0.08195, 0.00000, 0.00000, 0.02107, 0.02873, 0.05268, 0.00810, 0.07294, }, { -0.03177, -0.00733, -0.01059, -0.02383, -0.03177, -0.01906, -0.00433, -0.00477, -0.00367, -0.00147, } }; double error = .00001; Matrix inputMatrix = new YaleSparseMatrix(6, 10); for (int row = 0; row < 6; ++row) for (int col = 0; col < 10; ++col) inputMatrix.set(row, col, testInput[row][col]); Transform transform = new TfIdfTransform(); Matrix outputMatrix = transform.transform(inputMatrix); for (int row = 0; row < 6; ++row) { for (int col = 0; col < 10; ++col) assertEquals(testOutput[row][col], outputMatrix.get(row, col), error); } }
/** * Helper method to apply one animation to either an objectmap for blending or directly to the * bones. */ protected static void applyAnimation( final ObjectMap<Node, Transform> out, final Pool<Transform> pool, final float alpha, final Animation animation, final float time) { for (final NodeAnimation nodeAnim : animation.nodeAnimations) { final Node node = nodeAnim.node; node.isAnimated = true; // Find the keyframe(s) final int n = nodeAnim.keyframes.size - 1; int first = 0, second = -1; for (int i = 0; i < n; i++) { if (time >= nodeAnim.keyframes.get(i).keytime && time <= nodeAnim.keyframes.get(i + 1).keytime) { first = i; second = i + 1; break; } } // Apply the first keyframe: final Transform transform = tmpT; final NodeKeyframe firstKeyframe = nodeAnim.keyframes.get(first); transform.set(firstKeyframe.translation, firstKeyframe.rotation, firstKeyframe.scale); // Lerp the second keyframe if (second > first) { final NodeKeyframe secondKeyframe = nodeAnim.keyframes.get(second); final float t = (time - firstKeyframe.keytime) / (secondKeyframe.keytime - firstKeyframe.keytime); transform.lerp( secondKeyframe.translation, secondKeyframe.rotation, secondKeyframe.scale, t); } // Apply the transform, either directly to the bone or to out when blending if (out == null) transform.toMatrix4(node.localTransform); else { if (out.containsKey(node)) { if (alpha == 1.f) out.get(node).set(transform); else out.get(node).lerp(transform, alpha); } else { out.put(node, pool.obtain().set(transform)); } } } }