コード例 #1
0
        private static void GenerateCurvedIllusionPlaneVertexData(HardwareVertexBuffer vertexBuffer, int ySegments, int xSegments, float xSpace, float halfWidth, float ySpace, float halfHeight, Matrix4 xform, bool firstTime, bool normals, Quaternion orientation, float cameraPosition, float sphereRadius, float uTiles, float vTiles, int numberOfTexCoordSets, ref Vector3 min, ref Vector3 max, ref float maxSquaredLength)
        {
            Vector3 vec;
            Vector3 norm;
            float sphereDistance;
            unsafe {
                // lock the vertex buffer
                IntPtr data = vertexBuffer.Lock(BufferLocking.Discard);

                float* pData = (float*)data.ToPointer();

                for (int y = 0; y < ySegments + 1; ++y) {
                    for (int x = 0; x < xSegments + 1; ++x) {
                        // centered on origin
                        vec.x = (x * xSpace) - halfWidth;
                        vec.y = (y * ySpace) - halfHeight;
                        vec.z = 0.0f;

                        // transform by orientation and distance
                        vec = xform * vec;

                        // assign to geometry
                        *pData++ = vec.x;
                        *pData++ = vec.y;
                        *pData++ = vec.z;

                        // build bounds as we go
                        if (firstTime) {
                            min = vec;
                            max = vec;
                            maxSquaredLength = vec.LengthSquared;
                            firstTime = false;
                        } else {
                            min.Floor(vec);
                            max.Ceil(vec);
                            maxSquaredLength = MathUtil.Max(maxSquaredLength, vec.LengthSquared);
                        }

                        if (normals) {
                            norm = Vector3.UnitZ;
                            norm = orientation * norm;

                            *pData++ = vec.x;
                            *pData++ = vec.y;
                            *pData++ = vec.z;
                        }

                        // generate texture coordinates, normalize position, modify by orientation to return +y up
                        vec = orientation.Inverse() * vec;
                        vec.Normalize();

                        // find distance to sphere
                        sphereDistance = MathUtil.Sqrt(cameraPosition * cameraPosition * (vec.y * vec.y - 1.0f) + sphereRadius * sphereRadius) - cameraPosition * vec.y;

                        vec.x *= sphereDistance;
                        vec.z *= sphereDistance;

                        // use x and y on sphere as texture coordinates, tiled
                        float s = vec.x * (0.01f * uTiles);
                        float t = vec.z * (0.01f * vTiles);
                        for (int i = 0; i < numberOfTexCoordSets; i++) {
                            *pData++ = s;
                            *pData++ = (1 - t);
                        }
                    } // x
                } // y

                // unlock the buffer
                vertexBuffer.Unlock();
            } // unsafe
        }
コード例 #2
0
        /// <summary>
        /// Internal method for building an inverse Matrix4 from orientation / scale / position. 
        /// </summary>
        /// <remarks>
        ///	As makeTransform except it build the inverse given the same data as makeTransform, so
        ///	performing -translation, 1/scale, -rotate in that order.
        /// </remarks>
        /// <param name="position"></param>
        /// <param name="scale"></param>
        /// <param name="orientation"></param>
        /// <returns></returns>
        protected void MakeInverseTransform(Vector3 position, Vector3 scale, Quaternion orientation, ref Matrix4 destMatrix)
        {
            destMatrix = Matrix4.Identity;

            // Invert the parameters
            Vector3 invTranslate = -position;
            Vector3 invScale = Vector3.Zero;

            invScale.x = 1.0f / scale.x;
            invScale.y = 1.0f / scale.y;
            invScale.z = 1.0f / scale.z;

            Quaternion invRot = orientation.Inverse();

            // Because we're inverting, order is translation, rotation, scale
            // So make translation relative to scale & rotation
            invTranslate.x *= invScale.x; // scale
            invTranslate.y *= invScale.y; // scale
            invTranslate.z *= invScale.z; // scale
            invTranslate = invRot * invTranslate; // rotate

            // Next, make a 3x3 rotation matrix and apply inverse scale
            Matrix3 rot3x3 = invRot.ToRotationMatrix();
            Matrix3 scale3x3= Matrix3.Zero;

            scale3x3.m00 = invScale.x;
            scale3x3.m11 = invScale.y;
            scale3x3.m22 = invScale.z;

            // Set up final matrix with scale & rotation
            destMatrix = scale3x3 * rot3x3;

            destMatrix.Translation = invTranslate;
        }