1a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten/* 2a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * Copyright (C) 2010 The Android Open Source Project 3a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * 4a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License"); 5a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * you may not use this file except in compliance with the License. 6a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * You may obtain a copy of the License at 7a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * 8a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * http://www.apache.org/licenses/LICENSE-2.0 9a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * 10a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * Unless required by applicable law or agreed to in writing, software 11a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS, 12a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * See the License for the specific language governing permissions and 14a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * limitations under the License. 15a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten */ 16a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten 17a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten/* 3DLocation implementation */ 18a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten 19a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten#include "sles_allinclusive.h" 20a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten 21ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 22d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult I3DLocation_SetLocationCartesian(SL3DLocationItf self, const SLVec3D *pLocation) 23a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{ 24ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 25ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 26ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pLocation) { 27ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 28ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 29bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten I3DLocation *thiz = (I3DLocation *) self; 30ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SLVec3D locationCartesian = *pLocation; 31bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_lock_exclusive(thiz); 32bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mLocationCartesian = locationCartesian; 33bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mLocationActive = CARTESIAN_SET_SPHERICAL_UNKNOWN; 34bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_exclusive(thiz); 35ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 36ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 37ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 38ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 39a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten} 40a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten 41ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 42a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenstatic SLresult I3DLocation_SetLocationSpherical(SL3DLocationItf self, 43a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten SLmillidegree azimuth, SLmillidegree elevation, SLmillimeter distance) 44a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{ 45ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 46ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 47d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten if (!((-360000 <= azimuth) && (azimuth <= 360000) && 48d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten (-90000 <= elevation) && (elevation <= 90000) && 49ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten (0 <= distance) && (distance <= SL_MILLIMETER_MAX))) { 50ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 51ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 52bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten I3DLocation *thiz = (I3DLocation *) self; 53bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_lock_exclusive(thiz); 54bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mLocationSpherical.mAzimuth = azimuth; 55bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mLocationSpherical.mElevation = elevation; 56bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mLocationSpherical.mDistance = distance; 57bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mLocationActive = CARTESIAN_UNKNOWN_SPHERICAL_SET; 58bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_exclusive(thiz); 59ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 60ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 61ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 62ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 63a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten} 64a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten 65ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 66a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenstatic SLresult I3DLocation_Move(SL3DLocationItf self, const SLVec3D *pMovement) 67a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{ 68ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 69ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 70ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pMovement) { 71ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 72ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 73bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten I3DLocation *thiz = (I3DLocation *) self; 74ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SLVec3D movementCartesian = *pMovement; 75bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_lock_exclusive(thiz); 76ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten for (;;) { 77bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten enum CartesianSphericalActive locationActive = thiz->mLocationActive; 78ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten switch (locationActive) { 79ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten case CARTESIAN_COMPUTED_SPHERICAL_SET: 80ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten case CARTESIAN_SET_SPHERICAL_COMPUTED: // not in 1.0.1 81ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten case CARTESIAN_SET_SPHERICAL_REQUESTED: // not in 1.0.1 82ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten case CARTESIAN_SET_SPHERICAL_UNKNOWN: 83bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mLocationCartesian.x += movementCartesian.x; 84bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mLocationCartesian.y += movementCartesian.y; 85bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mLocationCartesian.z += movementCartesian.z; 86bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mLocationActive = CARTESIAN_SET_SPHERICAL_UNKNOWN; 87ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 88ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten case CARTESIAN_UNKNOWN_SPHERICAL_SET: 89bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mLocationActive = CARTESIAN_REQUESTED_SPHERICAL_SET; 90ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // fall through 91ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten case CARTESIAN_REQUESTED_SPHERICAL_SET: 92ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // matched by cond_broadcast in case multiple requesters 93ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten#if 0 94bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_cond_wait(thiz); 95ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten#else 96bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mLocationActive = CARTESIAN_COMPUTED_SPHERICAL_SET; 97ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten#endif 98ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten continue; 99ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten default: 100ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten assert(SL_BOOLEAN_FALSE); 101ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 102ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 103a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten break; 104a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten } 105bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_exclusive(thiz); 106ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 107a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten } 108ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 109ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 110a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten} 111a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten 112ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 113d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult I3DLocation_GetLocationCartesian(SL3DLocationItf self, SLVec3D *pLocation) 114a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{ 115ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 116ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 117ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pLocation) { 118ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 119ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 120bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten I3DLocation *thiz = (I3DLocation *) self; 121bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_lock_exclusive(thiz); 122ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten for (;;) { 123bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten enum CartesianSphericalActive locationActive = thiz->mLocationActive; 124ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten switch (locationActive) { 125ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten case CARTESIAN_COMPUTED_SPHERICAL_SET: 126ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten case CARTESIAN_SET_SPHERICAL_COMPUTED: // not in 1.0.1 127ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten case CARTESIAN_SET_SPHERICAL_REQUESTED: // not in 1.0.1 128ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten case CARTESIAN_SET_SPHERICAL_UNKNOWN: 129ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten { 130bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten SLVec3D locationCartesian = thiz->mLocationCartesian; 131bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_exclusive(thiz); 132ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pLocation = locationCartesian; 133ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 134ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 135ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten case CARTESIAN_UNKNOWN_SPHERICAL_SET: 136bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mLocationActive = CARTESIAN_REQUESTED_SPHERICAL_SET; 137ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // fall through 138ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten case CARTESIAN_REQUESTED_SPHERICAL_SET: 139ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // matched by cond_broadcast in case multiple requesters 140ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten#if 0 141bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_cond_wait(thiz); 142ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten#else 143bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mLocationActive = CARTESIAN_COMPUTED_SPHERICAL_SET; 144ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten#endif 145ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten continue; 146ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten default: 147ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten assert(SL_BOOLEAN_FALSE); 148bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_exclusive(thiz); 149ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten pLocation->x = 0; 150ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten pLocation->y = 0; 151ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten pLocation->z = 0; 152ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 153a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten } 154a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten break; 155a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten } 156ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 157a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten } 158ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 159ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 160a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten} 161a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten 162ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 163a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenstatic SLresult I3DLocation_SetOrientationVectors(SL3DLocationItf self, 164a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten const SLVec3D *pFront, const SLVec3D *pAbove) 165a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{ 166ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 167ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 168ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pFront || NULL == pAbove) { 169ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 170ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 171ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SLVec3D front = *pFront; 172ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SLVec3D above = *pAbove; 1737a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten // NTH Check for vectors close to zero or close to parallel 174bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten I3DLocation *thiz = (I3DLocation *) self; 175bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_lock_exclusive(thiz); 176bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mOrientationVectors.mFront = front; 177bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mOrientationVectors.mAbove = above; 178bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mOrientationActive = ANGLES_UNKNOWN_VECTORS_SET; 179bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mRotatePending = SL_BOOLEAN_FALSE; 180bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_exclusive(thiz); 181ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 182ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 183ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 184ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 185a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten} 186a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten 187ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 188a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenstatic SLresult I3DLocation_SetOrientationAngles(SL3DLocationItf self, 189a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten SLmillidegree heading, SLmillidegree pitch, SLmillidegree roll) 190a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{ 191ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 192ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 193d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten if (!((-360000 <= heading) && (heading <= 360000) && 194d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten (-90000 <= pitch) && (pitch <= 90000) && 195ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten (-360000 <= roll) && (roll <= 360000))) { 196ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 197ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 198bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten I3DLocation *thiz = (I3DLocation *) self; 199bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_lock_exclusive(thiz); 200bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mOrientationAngles.mHeading = heading; 201bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mOrientationAngles.mPitch = pitch; 202bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mOrientationAngles.mRoll = roll; 203bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mOrientationActive = ANGLES_SET_VECTORS_UNKNOWN; 204bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mRotatePending = SL_BOOLEAN_FALSE; 205bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_exclusive(thiz); 206ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 207ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 208ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 209ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 210a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten} 211a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten 212ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 213d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult I3DLocation_Rotate(SL3DLocationItf self, SLmillidegree theta, const SLVec3D *pAxis) 214a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{ 215ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 216ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 217ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (!((-360000 <= theta) && (theta <= 360000)) || (NULL == pAxis)) { 218ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 219ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 220ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SLVec3D axis = *pAxis; 2217a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten // NTH Check that axis is not (close to) zero vector, length does not matter 222bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten I3DLocation *thiz = (I3DLocation *) self; 223bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_lock_exclusive(thiz); 224bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten while (thiz->mRotatePending) 225ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten#if 0 226bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_cond_wait(thiz); 227ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten#else 228ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 229ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten#endif 230bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mTheta = theta; 231bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mAxis = axis; 232bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mRotatePending = SL_BOOLEAN_TRUE; 233bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_exclusive(thiz); 234ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 235ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 236ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 237ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 238a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten} 239a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten 240ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 241a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenstatic SLresult I3DLocation_GetOrientationVectors(SL3DLocationItf self, 242a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten SLVec3D *pFront, SLVec3D *pUp) 243a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{ 244ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 245ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 246ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pFront || NULL == pUp) { 247ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 248ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 249bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten I3DLocation *thiz = (I3DLocation *) self; 250bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_lock_shared(thiz); 251bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten SLVec3D front = thiz->mOrientationVectors.mFront; 252bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten SLVec3D up = thiz->mOrientationVectors.mUp; 253bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_shared(thiz); 254ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pFront = front; 255ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pUp = up; 256ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 257ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 258ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 259ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 260a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten} 261a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten 262ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 263a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenstatic const struct SL3DLocationItf_ I3DLocation_Itf = { 264a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DLocation_SetLocationCartesian, 265a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DLocation_SetLocationSpherical, 266a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DLocation_Move, 267a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DLocation_GetLocationCartesian, 268a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DLocation_SetOrientationVectors, 269a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DLocation_SetOrientationAngles, 270a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DLocation_Rotate, 271a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten I3DLocation_GetOrientationVectors 272a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}; 273a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten 274a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenvoid I3DLocation_init(void *self) 275a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{ 276bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten I3DLocation *thiz = (I3DLocation *) self; 277bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mItf = &I3DLocation_Itf; 278bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mLocationCartesian.x = 0; 279bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mLocationCartesian.y = 0; 280bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mLocationCartesian.z = 0; 281bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten memset(&thiz->mLocationSpherical, 0x55, sizeof(thiz->mLocationSpherical)); 282bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mLocationActive = CARTESIAN_SET_SPHERICAL_UNKNOWN; 283bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mOrientationAngles.mHeading = 0; 284bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mOrientationAngles.mPitch = 0; 285bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mOrientationAngles.mRoll = 0; 286bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten memset(&thiz->mOrientationVectors, 0x55, sizeof(thiz->mOrientationVectors)); 287bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mOrientationActive = ANGLES_SET_VECTORS_UNKNOWN; 288bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mTheta = 0x55555555; 289bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mAxis.x = 0x55555555; 290bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mAxis.y = 0x55555555; 291bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mAxis.z = 0x55555555; 292bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mRotatePending = SL_BOOLEAN_FALSE; 293a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten} 294